package com.xbongbong.paas.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.AdvancedRuleFieldOperatorConstant;
import com.xbongbong.paas.constant.FieldRelationConstant;
import com.xbongbong.paas.constant.FieldRelyConstant;
import com.xbongbong.paas.constant.LinkCompareConstant;
import com.xbongbong.paas.constant.LinkDisplayConstant;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.RuleFieldOperatorConstant;
import com.xbongbong.paas.constant.RuleFieldRelationConstant;
import com.xbongbong.paas.data.service.RichTextService;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasProcessDataEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.OptionalRangeEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.enums.BelongEnum;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.DefaultTypeEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.LinkConditionNeedFilterFieldEnum;
import com.xbongbong.paas.enums.LinkFieldDisplayEnum;
import com.xbongbong.paas.enums.LinkKeyExplainEnum;
import com.xbongbong.paas.enums.MobileScreenFieldTypeEnum;
import com.xbongbong.paas.enums.PaySheetTypeEnum;
import com.xbongbong.paas.enums.PaymentSheetTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.enums.SheetTypeEnum;
import com.xbongbong.paas.enums.WebScreenFieldTypeEnum;
import com.xbongbong.paas.field.DefaultAttrPoJo;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.LinkInfoPojo;
import com.xbongbong.paas.field.RelyPoJo;
import com.xbongbong.paas.field.SaasParticularAttributePoJo;
import com.xbongbong.paas.field.SubFormPoJo;
import com.xbongbong.paas.help.BusinessUserTeamHelp;
import com.xbongbong.paas.help.FormExplainHelp;
import com.xbongbong.paas.help.PaasFormHelp;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.help.analysis.data.FormDataLinkAddUpdateGetAnalysisDataHelp;
import com.xbongbong.paas.help.menu.InitCrmMenuHelp;
import com.xbongbong.paas.help.service.impl.FormDataLinkDataUpdateGetServiceImpl;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasProcessDataModel;
import com.xbongbong.paas.pojo.dto.ExplainCompareListDTO;
import com.xbongbong.paas.pojo.dto.ExplainRelationListDTO;
import com.xbongbong.paas.pojo.dto.ExplainRelyAttrListDTO;
import com.xbongbong.paas.pojo.dto.ExplainRelyBusinessAttrListDTO;
import com.xbongbong.paas.pojo.dto.ExplainScreenListDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.dto.FormDataUpdateGetDTO;
import com.xbongbong.paas.pojo.dto.FormExplainAddDTO;
import com.xbongbong.paas.pojo.dto.FormExplainListDTO;
import com.xbongbong.paas.pojo.dto.LinkCompareFieldDTO;
import com.xbongbong.paas.pojo.dto.LinkDisplayFieldDTO;
import com.xbongbong.paas.pojo.dto.LinkExplainListDTO;
import com.xbongbong.paas.pojo.dto.ParseSingleRowDataDTO;
import com.xbongbong.paas.pojo.dto.PartFormExplainListDTO;
import com.xbongbong.paas.pojo.dto.ProductDataRelyDTO;
import com.xbongbong.paas.pojo.vo.ExplainCompareListVO;
import com.xbongbong.paas.pojo.vo.ExplainRelationListVO;
import com.xbongbong.paas.pojo.vo.ExplainRelyAttrListVO;
import com.xbongbong.paas.pojo.vo.ExplainRelyBusinessAttrListVO;
import com.xbongbong.paas.pojo.vo.ExplainScreenListVO;
import com.xbongbong.paas.pojo.vo.FormExplainAddVO;
import com.xbongbong.paas.pojo.vo.FormExplainListVO;
import com.xbongbong.paas.pojo.vo.LinkCompareFieldVO;
import com.xbongbong.paas.pojo.vo.LinkDisplayFieldVO;
import com.xbongbong.paas.pojo.vo.LinkExplainListVO;
import com.xbongbong.paas.pojo.vo.LinkResultDataVO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.pojo.vo.ParseSingleRowDataVO;
import com.xbongbong.paas.pojo.vo.PartFormExplainListVO;
import com.xbongbong.paas.pojo.vo.ProductDataRelyVO;
import com.xbongbong.paas.service.PaasFormDataService;
import com.xbongbong.paas.service.PaasFormExplainService;
import com.xbongbong.paas.service.PackageService;
import com.xbongbong.paas.service.ProFormExplainService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.ReflectHelper;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.parent.explain.FormDataAddFormExplainHandlerName;
import com.xbongbong.pro.constant.ConditionLogicConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.constant.OperateLogicConstant;
import com.xbongbong.pro.domain.entity.FormConfigEntity;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.FieldConditionEnum;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.businessrule.enums.RuleConditionBusinessFieldEnum;
import com.xbongbong.pro.enums.businessrule.enums.RuleConditionFieldEnum;
import com.xbongbong.pro.enums.businessrule.enums.RuleFilterConditionEnum;
import com.xbongbong.pro.enums.businessrule.enums.RuleValueTypeEnum;
import com.xbongbong.pro.enums.businessrule.enums.RuleVersionEnum;
import com.xbongbong.saas.enums.TriggerConditionBusinessFieldEnum;
import com.xbongbong.pro.enums.errorcodes.BusinessTypeErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.ProductErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.TemplateErrorCodeEnum;
import com.xbongbong.pro.enums.fund.enums.ModelTypeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.form.pojo.RuleTargetPojo;
import com.xbongbong.pro.formdata.pojo.SaasSpecialParamPojo;
import com.xbongbong.pro.formdata.pojo.dto.SaasAnalysisDataDTO;
import com.xbongbong.pro.formexplain.pojo.FieldAndLogicPojo;
import com.xbongbong.pro.formexplain.pojo.LogicPojo;
import com.xbongbong.pro.formexplain.pojo.ReturnExplainPojo;
import com.xbongbong.pro.formexplain.pojo.ValueTypePojo;
import com.xbongbong.pro.formexplain.pojo.dto.DynamicManagerDTO;
import com.xbongbong.pro.formexplain.pojo.dto.ExplainFilterConditionDTO;
import com.xbongbong.pro.formexplain.pojo.dto.ExplainMapLinkDataDTO;
import com.xbongbong.pro.formexplain.pojo.dto.ExplainOperatorDTO;
import com.xbongbong.pro.formexplain.pojo.dto.FilterExplainByRuleDTO;
import com.xbongbong.pro.formexplain.pojo.dto.FormExplainAddBatchDTO;
import com.xbongbong.pro.formexplain.pojo.dto.FormExplainDeleteDTO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.dto.LinkFormItemDTO;
import com.xbongbong.pro.formexplain.pojo.dto.LinkKeyExplainListDTO;
import com.xbongbong.pro.formexplain.pojo.vo.DynamicManagerVO;
import com.xbongbong.pro.formexplain.pojo.vo.ExplainFilterConditionVO;
import com.xbongbong.pro.formexplain.pojo.vo.ExplainMapLinkDataVO;
import com.xbongbong.pro.formexplain.pojo.vo.ExplainOperatorVO;
import com.xbongbong.pro.formexplain.pojo.vo.FormExplainAddBatchVO;
import com.xbongbong.pro.formexplain.pojo.vo.FormExplainDeleteVO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.pro.formexplain.pojo.vo.LinkFormItemVO;
import com.xbongbong.pro.formexplain.pojo.vo.LinkKeyExplainListVO;
import com.xbongbong.pro.formexplain.pojo.vo.RuleFormExplainListVO;
import com.xbongbong.pro.fundset.pojo.FundSetTransitionPojo;
import com.xbongbong.pro.packageInfo.pojo.vo.BasePackageInfoVO;
import com.xbongbong.pro.paymentsheet.pojo.dto.AccountListDTO;
import com.xbongbong.pro.paymentsheet.pojo.vo.AccountListVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.constant.teammembers.TeamMembersConstant;
import com.xbongbong.saas.domain.entity.WorkOrderExplainEntity;
import com.xbongbong.saas.domain.entity.WorkOrderTemplateEntity;
import com.xbongbong.saas.domain.entity.ext.WorkOrderExplainEntityExt;
import com.xbongbong.saas.enums.FormConfigEnum;
import com.xbongbong.saas.enums.LinkProductRelyEnum;
import com.xbongbong.saas.enums.ListGroupEnum;
import com.xbongbong.saas.enums.MirrorModuleEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.OptionalRangeFieldEnum;
import com.xbongbong.saas.enums.PayBalanceEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.RepeatTypeEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.SheetAloneEnum;
import com.xbongbong.saas.enums.ShowTypeEnum;
import com.xbongbong.saas.enums.VisibleRangeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.BatchFlowBillEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.InventoryEnum;
import com.xbongbong.saas.enums.business.InvoiceEnum;
import com.xbongbong.saas.enums.business.OriStockEnum;
import com.xbongbong.saas.enums.business.PayPlanEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentBalanceEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.PaymentTaskEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.ProductSerialBalanceEnum;
import com.xbongbong.saas.enums.business.ProductionOrderEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.business.StockFlowBillEnum;
import com.xbongbong.saas.enums.business.SupplierContactEnum;
import com.xbongbong.saas.enums.business.SupplierEnum;
import com.xbongbong.saas.enums.business.WaitInstockEnum;
import com.xbongbong.saas.enums.business.WorkOrderEnum;
import com.xbongbong.saas.enums.business.WorkReportFieldEnum;
import com.xbongbong.saas.enums.dictionary.IsRedEnum;
import com.xbongbong.saas.enums.dictionary.PayPlanStatusEnum;
import com.xbongbong.saas.enums.dictionary.PaymentStatusEnum;
import com.xbongbong.saas.enums.product.PriceSetEnum;
import com.xbongbong.saas.help.ExplainHelp;
import com.xbongbong.saas.help.FundHelp;
import com.xbongbong.saas.help.LabelHelp;
import com.xbongbong.saas.help.SaasAddHelp;
import com.xbongbong.saas.help.SaasListHelp;
import com.xbongbong.saas.help.SaasUpdateHelp;
import com.xbongbong.saas.help.ShowFormatHelp;
import com.xbongbong.saas.model.FormConfigModel;
import com.xbongbong.saas.model.LinkProductRelyModel;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.saas.script.help.InitExplainsHelper;
import com.xbongbong.saas.service.FundSetService;
import com.xbongbong.saas.service.WorkOrderTemplateService;
import com.xbongbong.saas.service.toolbox.help.ProductHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.MirrorCompanyEntity;
import com.xbongbong.sys.domain.entity.MirrorInfoEntity;
import com.xbongbong.sys.domain.entity.RoleEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.DepartmentModel;
import com.xbongbong.sys.model.MirrorCompanyModel;
import com.xbongbong.sys.model.MirrorInfoModel;
import com.xbongbong.sys.model.RoleModel;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.util.FilterExplainUtil;
import com.xbongbong.workflow.domain.entity.WorkflowTransferDataEntity;
import com.xbongbong.workflow.model.WorkflowTransferDataModel;
import com.xbongbong.workflow.pojo.WorkflowTransferPOJO;
import com.xbongbong.workorder.service.WorkOrderStageService;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static java.util.stream.Collectors.toList;

/**
 * @author: wufeng
 * @date: 2018/9/10 10:08
 * @desrcption:
 */
@Service("paasFormExplainService")
public class PaasFormExplainServiceImpl implements PaasFormExplainService {

    private static final Logger LOG = LoggerFactory.getLogger(PaasFormExplainServiceImpl.class);

    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private PaasFormDataService paasFormDataService;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private PaasProcessDataModel paasProcessDataModel;
    @Resource
    private UserModel userModel;
    @Resource
    private DepartmentModel departmentModel;
    @Resource
    private WorkOrderExplainModel workOrderExplainModel;
    @Resource
    private WorkOrderTemplateService workOrderTemplateService;
    @Resource
    private WorkOrderStageService workOrderStageService;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private SaasAddHelp saasAddHelp;
    @Resource
    private SaasListHelp saasListHelp;
    @Resource
    private InitCrmMenuHelp initCrmMenuHelp;
    @Resource
    private FormDataLinkDataUpdateGetServiceImpl formDataLinkDataUpdateGetService;
    @Resource
    private SaasUpdateHelp saasUpdateHelp;
    @Resource
    private ShowFormatHelp showFormatHelp;
    @Resource
    private MirrorCompanyModel mirrorCompanyModel;
    @Resource
    private MirrorInfoModel mirrorInfoModel;
    @Resource
    private FormDataAddFormExplainHandlerName formDataAddFormExplainHandlerName;
    @Resource
    private FormConfigModel formConfigModel;
    @Resource
    private PaasFormHelp paasFormHelp;
    @Resource
    private PackageService packageService;
    @Resource
    private FormDataLinkAddUpdateGetAnalysisDataHelp formDataLinkAddUpdateGetAnalysisDataHelp;
    @Resource
    private FundHelp fundHelp;
    @Resource
    private LinkProductRelyModel linkProductRelyModel;
    @Resource
    private FormExplainHelp formExplainHelp;
    @Resource
    private ProductHelp productHelp;
    @Resource
    private LabelHelp labelHelp;
    @Resource
    private WorkflowTransferDataModel workflowTransferDataModel;
    @Resource
    private FundSetService fundSetService;
    @Resource
    private RoleModel roleModel;
    @Resource
    private ExplainHelp explainHelp;
    @Resource
    private BusinessUserTeamHelp businessUserTeamHelp;
    @Resource
    private RichTextService richTextService;
    @Resource
    private ProFormExplainService proFormExplainService;

    @Override
    public FormExplainAddVO add(FormExplainAddDTO formExplainAddDTO) throws XbbException {
        FormExplainAddVO formExplainAddVO = new FormExplainAddVO();
        try {
            String userId = formExplainAddDTO.getUserId();
            String corpid = formExplainAddDTO.getCorpid();
            String loginUserName = formExplainAddDTO.getLoginUserName();
            // 生成表单字段描述信息
            PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
            BeanUtil.copyProperties(formExplainAddDTO, paasFormExplainEntity);
            if (Objects.equals(formExplainAddDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(formExplainAddDTO.getBusinessType());
                if (Objects.isNull(xbbRefTypeEnum)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
                }
                PaasFormEntity paasFormEntity = paasFormModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(),corpid);
                if (Objects.isNull(paasFormEntity)) {
                    paasFormEntity = paasFormModel.getByBusinessTypeNoEnable(XbbRefTypeEnum.PRODUCT.getCode(),corpid);
                }
                // 若开启镜像就用镜像配置
                List<FieldAttrEntity> fieldList = new ArrayList<>();
                JSONArray fieldArray = getMirrorConfig(corpid, xbbRefTypeEnum.getAlias());
                FundSetTransitionPojo fundSetTransitionPojo = new FundSetTransitionPojo(corpid);
                if (Objects.nonNull(fieldArray)) {
                    fieldList = InitExplainsHelper.initSimpleFieldAttrEntity(xbbRefTypeEnum.getAlias(), fieldArray, paasFormEntity, fundSetTransitionPojo);
                } else if (!InitExplainsHelper.EMPTY_EXPLAIN.contains(formExplainAddDTO.getBusinessType())){
                    // 空解释可以直接调用corpid=0的默认解释
                    fieldList = InitExplainsHelper.initFieldAttrEntity(xbbRefTypeEnum.getAlias(), paasFormEntity, fundSetTransitionPojo, 0);
                }
                if (Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), formExplainAddDTO.getBusinessType())) {
                    initCrmMenuHelp.removeCompanyCustomerField(fieldList);
                }
                paasFormExplainEntity.setExplains(JSON.toJSONString(fieldList));
                paasFormExplainEntity.setCorpid(corpid);
                paasFormExplainEntity.setAppId(formExplainAddDTO.getAppId());
                paasFormExplainEntity.setMenuId(formExplainAddDTO.getMenuId());
                paasFormExplainEntity.setFormId(formExplainAddDTO.getFormId());
                paasFormExplainEntity.setBusinessType(formExplainAddDTO.getBusinessType());
                paasFormExplainEntity.setSaasMark(formExplainAddDTO.getSaasMark());
            } else {
                paasFormExplainEntity.setExplains(JSONObject.toJSONString(formExplainAddDTO.getFormList()));
            }

            paasFormExplainEntity.setCreatorId(formExplainAddDTO.getUserId());
            paasFormExplainModel.insert(paasFormExplainEntity);
            // 客户和线索的名称、电话判重设置存一份到表单配置表
            if (Objects.equals(formExplainAddDTO.getBusinessType(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()) || Objects.equals(formExplainAddDTO.getBusinessType(), XbbRefTypeEnum.CLUE.getCode())) {
                addCustomerFormConfig(corpid, formExplainAddDTO.getFormId(), formExplainAddDTO.getBusinessType());
            }
            // 初始化标签
            labelHelp.initLabel(corpid, formExplainAddDTO.getAppId(), formExplainAddDTO.getFormId(), formExplainAddDTO.getBusinessType(), formExplainAddDTO.getUserId(), true);
            formExplainAddVO.setFormExplainId(paasFormExplainEntity.getId());
            // 记录日志
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_ADD_FORM_EXPLAIN), loginUserName);
            mongoLogHelp.buildLog(corpid, userId, loginUserName, OperateModuleTypeEnum.PAAS_FORM_EXPLAIN, OperateTypeEnum.NEW, formExplainAddDTO.getFormId().toString(), "", memo, formExplainAddDTO.getHttpHeader());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("formExplainServiceImpl.add新建表单字段信息出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formExplainAddVO;
    }

    @Override
    public FormExplainAddBatchVO addBatch(FormExplainAddBatchDTO formExplainAddBatchDTO) throws XbbException {
        return proFormExplainService.addBatch(formExplainAddBatchDTO);
    }

    @Override
    public FormExplainListVO linkList(FormExplainListDTO formExplainListDTO) throws XbbException {
        FormExplainListVO formExplainListVO = new FormExplainListVO();
        try {
            String corpid = formExplainListDTO.getCorpid();
            Integer businessType = formExplainListDTO.getBusinessType();
            PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), businessType)) {
                // 工单逻辑
                WorkOrderExplainEntityExt workOrderExplainEntityExt = workOrderExplainModel.getByFormId(formExplainListDTO.getFormId(), corpid);
                if (Objects.isNull(workOrderExplainEntityExt)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                BeanUtil.copyProperties(workOrderExplainEntityExt, paasFormExplainEntity);
            } else {
                paasFormExplainEntity = paasFormExplainModel.getByFormId(formExplainListDTO.getFormId(), corpid);
            }
            if (paasFormExplainEntity != null) {
                // 是否为联系人
                boolean isContact = Objects.equals(XbbRefTypeEnum.CONTACT.getCode(), businessType) && Objects.equals(DistributorMarkEnum.OTHER.getCode(), paasFormExplainEntity.getDistributorMark());
                List<FieldAttrEntity> explainList = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                List<FieldAttrEntity> formShowExplainList = new ArrayList<>();
                Iterator<FieldAttrEntity> iterator = explainList.iterator();
                while (iterator.hasNext()) {
                    FieldAttrEntity fieldAttrEntity = iterator.next();
                    Integer showType = fieldAttrEntity.getShowType();
                    Boolean invisible = Objects.nonNull(fieldAttrEntity.getShowType()) && (ShowTypeEnum.LIST.getCode() == showType || ShowTypeEnum.DETAIL.getCode() == showType
                            || ShowTypeEnum.LIST_DETAIL.getCode() == showType || ShowTypeEnum.NONE.getCode() == showType) && Objects.equals(fieldAttrEntity.getEditHide(),  1);
                    FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldAttrEntity.getFieldType());
                    // 过滤掉saas字段，以及新建编辑不可见字段
                    List<Integer> unFilterFieldType = new ArrayList<>();
                    unFilterFieldType.add(FieldTypeEnum.CONTACT_NUMBER.getType());
                    unFilterFieldType.add(FieldTypeEnum.PRODUCT_STOCK.getType());
                    unFilterFieldType.add(FieldTypeEnum.SPECIFICATION.getType());
                    unFilterFieldType.add(FieldTypeEnum.RICH_TEXT.getType());
                    if (Objects.equals(paasFormExplainEntity.getBusinessType(),XbbRefTypeEnum.PRODUCT.getCode()) && ProductEnum.linkAttrCanShow(fieldAttrEntity.getAttr())){
                        formShowExplainList.add(fieldAttrEntity);
                    }
                    if (Objects.equals(businessType, XbbRefTypeEnum.PRODUCT.getCode()) && ProductEnum.linkAttrNotShow(fieldAttrEntity.getAttr())) {
                        invisible = true;
                    } else if (Objects.equals(businessType, XbbRefTypeEnum.SERVICE_PROJECT.getCode()) &&
                            (Objects.equals(fieldAttrEntity.getAttr(), VisibleRangeEnum.VISIBLE_DEPT.getAttr()) || Objects.equals(fieldAttrEntity.getAttr(), VisibleRangeEnum.VISIBLE_USER.getAttr()))) {
                        invisible = true;
                    }
                    if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode()) && Objects.equals(WorkOrderEnum.MANAGER_ID.getAttr(), fieldAttrEntity.getAttr())) {
                        invisible = true;
                    }
                    if (Objects.isNull(fieldTypeEnum)) {
                        System.out.println();
                    }
                    if (invisible || Objects.equals(fieldAttrEntity.getIsOpen(), 2) || (Objects.equals(BelongEnum.SAAS.getAlias(), fieldTypeEnum.getBelong()) && !unFilterFieldType.contains(fieldTypeEnum.getType()))){
                        iterator.remove();
                        continue;
                    }
                    // 联系人头像只存在数据库，未存es
                    if (isContact && Objects.equals(fieldAttrEntity.getAttr(), ContactEnum.AVATAR.getAttr())) {
                        iterator.remove();
                        continue;
                    }
                }
                formExplainListVO.setFormShowExplainList(formShowExplainList);
                formExplainListVO.setFormExplainList(explainList);
                formExplainListVO.setAppId(paasFormExplainEntity.getAppId());
                formExplainListVO.setFormExplainId(paasFormExplainEntity.getFormId());
                formExplainListVO.setFormId(paasFormExplainEntity.getFormId());
            } else {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormExplain数据库搜索表单字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formExplainListVO;
    }


    @Override
    public ExplainCompareListVO compareList(ExplainCompareListDTO explainCompareListDTO) throws XbbException {
        ExplainCompareListVO explainCompareListVO = new ExplainCompareListVO();
        try {
            Map<String, Object> param = BeanUtil.convertBean2Map(explainCompareListDTO, true);
            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            List<PaasFormExplainEntity> list = paasFormExplainModel.list(param);
            if (list == null || list.isEmpty()) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            PaasFormExplainEntity paasFormExplainEntity = list.get(0);
            JSONArray jsonArray = new JSONArray();
            JSONArray explain = JSON.parseArray(paasFormExplainEntity.getExplains());
            for (Object object : explain) {
                JSONObject jsonObject = (JSONObject) object;
                Integer fieldType = jsonObject.getInteger("fieldType");
                FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
                if (fieldTypeEnum != null && ReflectHelper.exist(new FieldRelationConstant(), fieldTypeEnum.getAlias().toUpperCase())) {
                    jsonArray.add(object);
                }
            }
            explainCompareListVO.setFormExplainList(jsonArray);
            explainCompareListVO.setAppId(paasFormExplainEntity.getAppId());
            explainCompareListVO.setFormExplainId(paasFormExplainEntity.getFormId());
            explainCompareListVO.setFormId(paasFormExplainEntity.getFormId());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormExplain数据库搜索表单对比字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return explainCompareListVO;
    }

    @Override
    public ExplainScreenListVO screenList(ExplainScreenListDTO explainScreenListDTO) throws XbbException {
        ExplainScreenListVO explainScreenListVO = new ExplainScreenListVO();
        try {
            String corpid = explainScreenListDTO.getCorpid();
            Map<String, Object> param = BeanUtil.convertBean2Map(explainScreenListDTO, true);
            PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
            boolean delaultWorkOrder = false;
            boolean delaultWorkReport = false;
            if (Objects.equals(explainScreenListDTO.getSubBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode()) || Objects.equals(explainScreenListDTO.getSubBusinessType(), XbbRefTypeEnum.WORK_ORDER_ROB.getCode())) {
                Long formId = explainScreenListDTO.getFormId();
                WorkOrderExplainEntity workOrderExplainEntity;
                if (Objects.equals(formId, 0L)) {
                    delaultWorkOrder = true;
                    workOrderExplainEntity = workOrderExplainModel.getDefaultAllListExplain(corpid);
                    if (Objects.isNull(workOrderExplainEntity)) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                    }
                } else {
                    List<WorkOrderExplainEntity> list = workOrderExplainModel.list(param);
                    if (list == null || list.isEmpty()) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                    }
                    paasFormExplainEntity = new PaasFormExplainEntity();
                    workOrderExplainEntity = list.get(0);
                }
                BeanUtil.copyProperties(workOrderExplainEntity, paasFormExplainEntity);
            } else if (Objects.equals(explainScreenListDTO.getSubBusinessType(), XbbRefTypeEnum.WORK_REPORT.getCode())){
                Long formId = explainScreenListDTO.getFormId();
                if (Objects.equals(formId, 0L)) {
                    delaultWorkReport = true;
                    paasFormExplainEntity = paasFormExplainModel.getWorkReportDefaultAllListExplain();
                    if (Objects.isNull(paasFormExplainEntity)) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                    }
                } else {
                    param.clear();
                    param.put(ParameterConstant.FORMID,explainScreenListDTO.getFormId());
                    param.put(ParameterConstant.CORPID,explainScreenListDTO.getCorpid());
                    param.put(ParameterConstant.APPID,explainScreenListDTO.getAppId());
                    List<PaasFormExplainEntity> list = paasFormExplainModel.list(param);
                    if (list == null || list.isEmpty()) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                    }
                    paasFormExplainEntity = list.get(0);
                }
            } else{
                // 期初库存的解释
                if (Objects.equals(explainScreenListDTO.getBusinessType(),XbbRefTypeEnum.ORI_STOCK.getCode())){
                    paasFormExplainEntity = paasFormExplainModel.getSystemDefaultExplain(XbbRefTypeEnum.ORI_STOCK.getCode());
                    if (Objects.isNull(paasFormExplainEntity)) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                    }
                    List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                    List<FieldAttrEntity> productDetailList = explainList.stream().filter(item -> Objects.equals(item.getAttr(), OriStockEnum.PRODUCT_DETAIL.getAttr())).collect(toList());
                    if (CollectionsUtil.isEmpty(productDetailList)){
                        throw new XbbException(ProductErrorCodeEnum.API_ERROR_205035);
                    }
                    FieldAttrEntity productDetail = productDetailList.get(0);
                    SubFormPoJo productDetailSubForm = productDetail.getSubForm();
                    paasFormExplainEntity.setExplains(JSON.toJSONString(productDetailSubForm.getItems()));
                }  else if (Objects.equals(explainScreenListDTO.getBusinessType(), XbbRefTypeEnum.PRODUCT.getCode()) && (Objects.equals(explainScreenListDTO.getFormId(), ListGroupEnum.GUARANTEE_SEARCH.getCode().longValue())) || Objects.equals(explainScreenListDTO.getFormId(), ListGroupEnum.WARNING_SEARCH.getCode().longValue())) {
                    paasFormExplainEntity = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(), corpid);
                    if (Objects.isNull(paasFormExplainEntity)) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                    }
                } else if (Objects.equals(explainScreenListDTO.getBusinessType(), XbbRefTypeEnum.PRICE_SET_PRODUCT.getCode())) {
                    // 生成表头
                    List<FieldAttrEntity> fieldList = productHelp.getProductPriceFieldList(corpid);
                    for (FieldAttrEntity entity : fieldList) {
                        if(PriceSetEnum.ADAPTER_TYPE.getAttr().equals(entity.getAttr())){
                            entity.setAttrName("价目对象");
                        }
                    }
                    paasFormExplainEntity = new PaasFormExplainEntity();
                    paasFormExplainEntity.setExplains(JSON.toJSONString(fieldList));
                }else if (Objects.equals(explainScreenListDTO.getBusinessType(), XbbRefTypeEnum.MARKETING_ACTIVITY_MANAGEMENT.getCode())
                        || Objects.equals(explainScreenListDTO.getBusinessType(), XbbRefTypeEnum.PROMOTION_ACTIVITY_MANAGEMENT.getCode())
                        || Objects.equals(explainScreenListDTO.getBusinessType(), XbbRefTypeEnum.WRITE_OFF_RECORD.getCode())
                        || Objects.equals(explainScreenListDTO.getBusinessType(), XbbRefTypeEnum.KNOWLEDGE_BASE.getCode())) {
                    paasFormExplainEntity = paasFormExplainModel.getSystemDefaultExplain(explainScreenListDTO.getBusinessType());
                } else {
                    if (Objects.isNull(explainScreenListDTO.getFormId())) {
                        paasFormExplainEntity = paasFormExplainModel.getByBusinessType(explainScreenListDTO.getBusinessType(), corpid);
                    }else if (Objects.equals(XbbRefTypeEnum.WORK_ORDER_V2.getCode(), explainScreenListDTO.getBusinessType()) && Objects.equals(0L, explainScreenListDTO.getFormId()) ) {
                        paasFormExplainEntity = paasFormExplainModel.getSystemDefaultExplain(XbbRefTypeEnum.WORK_ORDER_V2.getCode());
                    } else {
                        paasFormExplainEntity = paasFormExplainModel.getByFormId(explainScreenListDTO.getFormId(), corpid);
                    }
                    if (Objects.isNull(paasFormExplainEntity) || Objects.equals(paasFormExplainEntity.getDel(), DelEnum.DELETE.getDel())) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                    }
                }

            }

            JSONArray jsonArray = new JSONArray();
            List<FieldAttrEntity> explain = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            PaasFormEntity productForm;
            if (delaultWorkOrder){
                Iterator<FieldAttrEntity> iterator = explain.iterator();
                while (iterator.hasNext()) {
                    FieldAttrEntity fieldAttrEntity = iterator.next();
                    if (Objects.equals(fieldAttrEntity.getAttr(), WorkOrderEnum.SPARE_PARTS.getAttr())) {
                        productForm = paasFormModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(), corpid);
                        int index = 0;
                        FieldAttrEntity productItem = new FieldAttrEntity();
                        List<FieldAttrEntity> fieldList = (List<FieldAttrEntity>) fieldAttrEntity.getSubForm().getItems();
                        for (FieldAttrEntity item : fieldList) {
                            if (Objects.equals(item.getAttr(), SelectProductEnum.PRODUCT.getAttr())) {
                                LinkInfoPojo infoPojo = item.getLinkInfo();
                                infoPojo.setLinkAppId(productForm.getAppId());
                                infoPojo.setLinkFormId(productForm.getId());
                                infoPojo.setLinkMenuId(productForm.getMenuId());
                                productItem = item;
                                productItem.setLinkInfo(infoPojo);
                                break;
                            }
                            index++;
                        }
                        fieldList.set(index, productItem);
                        fieldAttrEntity.getSubForm().setItems(fieldList);
                    }
                    if (Objects.equals(fieldAttrEntity.getAttr(), WorkOrderEnum.STAGE.getAttr())) {
                        // 全部列表移除阶段的筛选
                        iterator.remove();
                    }
                }
            } else if (Objects.equals(explainScreenListDTO.getSubBusinessType(), XbbRefTypeEnum.STOCK_FLOW_BILL.getCode()) || Objects.equals(explainScreenListDTO.getSubBusinessType(), XbbRefTypeEnum.STOCK_STANDING_BOOK.getCode())) {
                // 莫得办法，只能模拟关联产品解释
                List<String> filterList = Arrays.asList(StockFlowBillEnum.NAME.getAttr(), StockFlowBillEnum.TYPE.getAttr(), StockFlowBillEnum.WAREHOUSE_ID.getAttr());
                productForm = paasFormModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(), corpid);
                Iterator<FieldAttrEntity> iterator = explain.iterator();
                while (iterator.hasNext()) {
                    FieldAttrEntity fieldAttrEntity = iterator.next();
                    if (!filterList.contains(fieldAttrEntity.getAttr())) {
                        iterator.remove();
                    } else if (Objects.equals(fieldAttrEntity.getAttr(), StockFlowBillEnum.NAME.getAttr())) {
                        fieldAttrEntity.setSubForm(new SubFormPoJo());
                        fieldAttrEntity.getSubForm().setItems(new ArrayList<>());
                        FieldAttrEntity subForm = new FieldAttrEntity();
                        subForm.setSaasAttr(XbbRefTypeEnum.PRODUCT.getAlias());
                        LinkInfoPojo infoPojo = new LinkInfoPojo();
                        infoPojo.setLinkAppId(productForm.getAppId());
                        infoPojo.setLinkFormId(productForm.getId());
                        infoPojo.setLinkMenuId(productForm.getMenuId());
                        infoPojo.setLinkBusinessType(productForm.getBusinessType());
                        infoPojo.setLinkSaasMark(productForm.getSaasMark());
                        subForm.setLinkInfo(infoPojo);
                        List<FieldAttrEntity> fieldList = (List<FieldAttrEntity>) fieldAttrEntity.getSubForm().getItems();
                        fieldList.add(subForm);
                        fieldAttrEntity.getSubForm().setItems(fieldList);
                    }
                }
            } else if (Objects.equals(explainScreenListDTO.getSubBusinessType(), XbbRefTypeEnum.BATCH_FLOW_BILL.getCode())) {
                // 莫得办法，只能模拟关联产品解释
                productForm = paasFormModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(), corpid);
                List<String> filterList = Arrays.asList(BatchFlowBillEnum.NAME.getAttr(), BatchFlowBillEnum.TYPE.getAttr(), BatchFlowBillEnum.WAREHOUSE_ID.getAttr(), BatchFlowBillEnum.BATCH.getAttr());
                Iterator<FieldAttrEntity> iterator = explain.iterator();
                while (iterator.hasNext()) {
                    FieldAttrEntity fieldAttrEntity = iterator.next();
                    if (!filterList.contains(fieldAttrEntity.getAttr())) {
                        iterator.remove();
                    } else if (Objects.equals(fieldAttrEntity.getAttr(), BatchFlowBillEnum.NAME.getAttr())) {
                        fieldAttrEntity.setSubForm(new SubFormPoJo());
                        fieldAttrEntity.getSubForm().setItems(new ArrayList<>());
                        FieldAttrEntity subForm = new FieldAttrEntity();
                        subForm.setSaasAttr(XbbRefTypeEnum.PRODUCT.getAlias());
                        LinkInfoPojo infoPojo = new LinkInfoPojo();
                        infoPojo.setLinkAppId(productForm.getAppId());
                        infoPojo.setLinkFormId(productForm.getId());
                        infoPojo.setLinkMenuId(productForm.getMenuId());
                        infoPojo.setLinkBusinessType(productForm.getBusinessType());
                        infoPojo.setLinkSaasMark(productForm.getSaasMark());
                        subForm.setLinkInfo(infoPojo);
                        List<FieldAttrEntity> fieldList = (List<FieldAttrEntity>) fieldAttrEntity.getSubForm().getItems();
                        fieldList.add(subForm);
                        fieldAttrEntity.getSubForm().setItems(fieldList);
                    } else if (Objects.equals(fieldAttrEntity.getAttr(), BatchFlowBillEnum.BATCH.getAttr())) {
                       fieldAttrEntity.setFieldType(FieldTypeEnum.BATCH.getType());
                    }
                }
            } else if (Objects.equals(explainScreenListDTO.getSubBusinessType(), XbbRefTypeEnum.SEQ_SEARCH.getCode())) {
                // 莫得办法，只能模拟关联产品解释
                productForm = paasFormModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(), corpid);
                List<String> filterList = Arrays.asList(ProductSerialBalanceEnum.SEQ.getAttr(), ProductSerialBalanceEnum.WAREHOUSE_ID.getAttr(), ProductSerialBalanceEnum.NAME.getAttr());
                Iterator<FieldAttrEntity> iterator = explain.iterator();
                while (iterator.hasNext()) {
                    FieldAttrEntity fieldAttrEntity = iterator.next();
                    if (!filterList.contains(fieldAttrEntity.getAttr())) {
                        iterator.remove();
                    } else if (Objects.equals(fieldAttrEntity.getAttr(), ProductSerialBalanceEnum.NAME.getAttr())) {
                        fieldAttrEntity.setSubForm(new SubFormPoJo());
                        fieldAttrEntity.getSubForm().setItems(new ArrayList<>());
                        FieldAttrEntity subForm = new FieldAttrEntity();
                        subForm.setSaasAttr(XbbRefTypeEnum.PRODUCT.getAlias());
                        LinkInfoPojo infoPojo = new LinkInfoPojo();
                        infoPojo.setLinkAppId(productForm.getAppId());
                        infoPojo.setLinkFormId(productForm.getId());
                        infoPojo.setLinkMenuId(productForm.getMenuId());
                        infoPojo.setLinkBusinessType(productForm.getBusinessType());
                        infoPojo.setLinkSaasMark(productForm.getSaasMark());
                        subForm.setLinkInfo(infoPojo);
                        List<FieldAttrEntity> fieldList = (List<FieldAttrEntity>) fieldAttrEntity.getSubForm().getItems();
                        fieldList.add(subForm);
                        fieldAttrEntity.getSubForm().setItems(fieldList);
                    }
                }
            } else if (Objects.equals(explainScreenListDTO.getBusinessType(), XbbRefTypeEnum.PRODUCT.getCode()) && (Objects.equals(explainScreenListDTO.getFormId(), ListGroupEnum.GUARANTEE_SEARCH.getCode().longValue())) || Objects.equals(explainScreenListDTO.getFormId(), ListGroupEnum.WARNING_SEARCH.getCode().longValue())) {
                productForm = paasFormModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(), corpid);
                Iterator<FieldAttrEntity> iterator = explain.iterator();
                List<String> filterList = Collections.singletonList(ProductEnum.WAREHOUSE.getAttr());
                while (iterator.hasNext()) {
                    FieldAttrEntity fieldAttrEntity = iterator.next();
                    if (filterList.contains(fieldAttrEntity.getAttr())) {
                        fieldAttrEntity.setFieldType(fieldAttrEntity.getFieldType());
                        LinkInfoPojo infoPojo = new LinkInfoPojo();
                        infoPojo.setLinkAppId(paasFormExplainEntity.getAppId());
                        infoPojo.setLinkFormId(paasFormExplainEntity.getFormId());
                        infoPojo.setLinkMenuId(paasFormExplainEntity.getMenuId());
                        infoPojo.setLinkBusinessType(paasFormExplainEntity.getBusinessType());
                        infoPojo.setLinkSaasMark(paasFormExplainEntity.getSaasMark());
                        fieldAttrEntity.setLinkInfo(infoPojo);
                    } else if (Objects.equals(fieldAttrEntity.getAttr(), ProductEnum.NAME.getAttr())) {
                        fieldAttrEntity.setFieldType(FieldTypeEnum.SELECT_PRODUCT.getType());
                        fieldAttrEntity.setSubForm(new SubFormPoJo());
                        fieldAttrEntity.getSubForm().setItems(new ArrayList<>());
                        FieldAttrEntity subForm = new FieldAttrEntity();
                        subForm.setSaasAttr(XbbRefTypeEnum.PRODUCT.getAlias());
                        LinkInfoPojo infoPojo = new LinkInfoPojo();
                        infoPojo.setLinkAppId(productForm.getAppId());
                        infoPojo.setLinkFormId(productForm.getId());
                        infoPojo.setLinkMenuId(productForm.getMenuId());
                        infoPojo.setLinkBusinessType(productForm.getBusinessType());
                        infoPojo.setLinkSaasMark(productForm.getSaasMark());
                        subForm.setLinkInfo(infoPojo);
                        List<FieldAttrEntity> fieldList = (List<FieldAttrEntity>) fieldAttrEntity.getSubForm().getItems();
                        fieldList.add(subForm);
                        fieldAttrEntity.getSubForm().setItems(fieldList);
                    } else {
                        iterator.remove();
                    }
                }
                if (Objects.equals(explainScreenListDTO.getFormId(), ListGroupEnum.GUARANTEE_SEARCH.getCode().longValue())) {
                    FieldAttrEntity batchField = new FieldAttrEntity();
                    batchField.setAttr(SelectProductEnum.BATCH.getSaasAttr());
                    batchField.setAttrName(SelectProductEnum.BATCH.getAttrName());
                    batchField.setFieldType(FieldTypeEnum.BATCH.getType());
                    explain.add(batchField);

                    FieldAttrEntity warehouseField = new FieldAttrEntity();
                    warehouseField.setAttr(ProductEnum.WAREHOUSE.getAttr());
                    warehouseField.setAttrName(ProductEnum.WAREHOUSE.getAttrName());
                    warehouseField.setFieldType(ProductEnum.WAREHOUSE.getFieldType());
                    explain.add(warehouseField);

                    //explain.removeIf(item -> Objects.equals(item.getAttr(), ProductEnum.WAREHOUSE.getAttr()));
                }
            }
            if (delaultWorkReport){

            }
            explainScreenListVO.setExplainList(explain);
            saasListHelp.handelSaasSpecialList(explain, explainScreenListDTO.getBusinessType(), explainScreenListDTO.getSubBusinessType());
            if (Objects.equals(explainScreenListDTO.getSubBusinessType(),XbbRefTypeEnum.WAIT_INSTOCK_PURCHASE.getCode())
                    || Objects.equals(XbbRefTypeEnum.WAIT_OUTSTOCK.getCode(),explainScreenListDTO.getSubBusinessType())
                    || Objects.equals(XbbRefTypeEnum.WAIT_PURCHASE.getCode(),explainScreenListDTO.getSubBusinessType())
                    || Objects.equals(XbbRefTypeEnum.SMART_REPLENISHMENT.getCode(),explainScreenListDTO.getSubBusinessType())){
                waitSeriesExplainProcess(explain, corpid, explainScreenListDTO);
            }
            for (FieldAttrEntity object : explain) {
                // 字段回收站处理
                if (Objects.equals(object.getIsOpen(), 2)) {
                    continue;
                }
                // 过滤不可见字段以及未开启字段
                if (Objects.equals(object.getVisible(), 0)) {
                    continue;
                }
                if (Objects.equals(object.getIsOpen(), 0)) {
                    continue;
                }
                //TODO 客户业务下 过滤主联系人电话和主联系人名称 后续可能会需要做
                if (Objects.equals(explainScreenListDTO.getBusinessType(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())) {
                    if (Objects.equals(object.getAttr(), CustomerManagementEnum.CONTACT_PHONE.getAttr()) || Objects.equals(object.getAttr(), CustomerManagementEnum.CONTACT_NAME.getAttr())) {
                        //如果是客户自定义字段，则不过滤主联系人啊
                        if (Objects.equals(object.getIsRedundant(), 0)) {
                            continue;
                        }
                    }
                } else if (Objects.equals(explainScreenListDTO.getSubBusinessType(), XbbRefTypeEnum.PREPAYMENT_BALANCE.getCode())) {
                    if (Objects.equals(object.getAttr(), PaymentBalanceEnum.CONTRACT_COUNT.getAttr())) {
                        continue;
                    }
                } else if (Objects.equals(explainScreenListDTO.getSubBusinessType(), XbbRefTypeEnum.PREPAY_BALANCE.getCode())) {
                    if (Objects.equals(object.getAttr(), PayBalanceEnum.PURCHASE_COUNT.getAttr())) {
                        continue;
                    }
                }
                if(Objects.equals(explainScreenListDTO.getSubBusinessType(), XbbRefTypeEnum.STOCK_SEARCH.getCode()) || Objects.equals(explainScreenListDTO.getSubBusinessType(), XbbRefTypeEnum.WARNING_SEARCH.getCode())
                        || Objects.equals(explainScreenListDTO.getSubBusinessType(), XbbRefTypeEnum.GUARANTEE_SEARCH.getCode())){
                    if(Objects.equals(object.getAttr(), ProductEnum.VISBLE_USER.getAttr()) || Objects.equals(object.getAttr(), ProductEnum.VISBLE_DEPT.getAttr())
                            || Objects.equals(object.getAttr(), ProductEnum.STOCK.getAttr()) || Objects.equals(object.getAttr(), ProductEnum.COST.getAttr())){
                        continue;
                    }
                }
                // 工作报告的创建人名字改为提交人
                if(Objects.equals(explainScreenListDTO.getBusinessType(),XbbRefTypeEnum.WORK_REPORT.getCode()) && Objects.equals(object.getAttr(), WorkReportFieldEnum.CREATOR_ID.getAttr())){
                    object.setAttrName(I18nMessageUtil.getMessage(I18nStringConstant.SUBMITTER));
                }
                Integer fieldType = object.getFieldType();
                if (Objects.equals(explainScreenListDTO.getPlatform(), PlatFormEnum.WEB.getValue())) {
                    WebScreenFieldTypeEnum webScreenFieldTypeEnum = WebScreenFieldTypeEnum.getByCode(fieldType);
                    if(webScreenFieldTypeEnum == null || Objects.equals(explainScreenListDTO.getBusinessType(),XbbRefTypeEnum.ORI_STOCK.getCode())) {
                        jsonArray.add(object);
                    }
                } else {
                    MobileScreenFieldTypeEnum mobileScreenFieldTypeEnum = MobileScreenFieldTypeEnum.getByCode(fieldType);
                    if (mobileScreenFieldTypeEnum == null) {
                        jsonArray.add(object);
                    }
                }
            }
            explainScreenListVO.setFormExplainList(jsonArray);
            explainScreenListVO.setAppId(paasFormExplainEntity.getAppId());
            explainScreenListVO.setFormExplainId(paasFormExplainEntity.getFormId());
            explainScreenListVO.setFormId(paasFormExplainEntity.getFormId());
            if (Objects.equals(explainScreenListDTO.getSubBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode()) || Objects.equals(explainScreenListDTO.getSubBusinessType(), XbbRefTypeEnum.WORK_ORDER_ROB.getCode())) {
                explainScreenListVO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                explainScreenListVO.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
            } else {
                explainScreenListVO.setSaasMark(paasFormExplainEntity.getSaasMark());
                explainScreenListVO.setBusinessType(paasFormExplainEntity.getBusinessType());
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormExplain数据库搜索表单对比字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return explainScreenListVO;
    }

    @Override
    public ExplainRelationListVO relationList(ExplainRelationListDTO explainCompareListDTO) throws XbbException {
        ExplainRelationListVO explainRelationListVO = new ExplainRelationListVO();
        try {
            FilterExplainByRuleDTO filterExplainByRuleDTO = new FilterExplainByRuleDTO();
            BeanUtil.copyProperties(explainCompareListDTO, filterExplainByRuleDTO);
            List<FieldAttrEntity> jsonArray = getFilterExplainListByRule(new FieldRelationConstant(), filterExplainByRuleDTO, explainCompareListDTO.getFieldType());
            // 添加数据id作为条件
            formExplainHelp.addDataIdAsCondition(jsonArray, explainCompareListDTO.getFieldType(), filterExplainByRuleDTO, true);
            // 入库单、出库单不需要返回系统关联字段
            removeLinkBusiness(jsonArray, explainCompareListDTO.getFieldType(), explainCompareListDTO.getBusinessType());
            explainRelationListVO.setFormExplainList(jsonArray);
            explainRelationListVO.setAppId(explainCompareListDTO.getAppId());
            explainRelationListVO.setMenuId(explainCompareListDTO.getMenuId());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormExplain数据库搜索表单匹配字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return explainRelationListVO;
    }

    /**
     * 关联表单可选择字段
     * @param explainRelyAttrListDTO
     * @return
     * @author xingxing.xiao
     * @date 2020/07/31 16:42
     */
    @Override
    public ExplainRelyAttrListVO relyAttrList(ExplainRelyAttrListDTO explainRelyAttrListDTO) throws XbbException {
        ExplainRelyAttrListVO formExplainListVO = new ExplainRelyAttrListVO();
        try {
            String corpid = explainRelyAttrListDTO.getCorpid();
            PaasFormExplainEntity paasFormExplainEntity = proFormHelp.getExplainEntity(corpid, explainRelyAttrListDTO.getFormId(), explainRelyAttrListDTO.getBusinessType());

            if(paasFormExplainEntity != null ) {
                PaasFormEntity paasFormEntity = proFormHelp.getPaasForm(explainRelyAttrListDTO.getFormId(), explainRelyAttrListDTO.getBusinessType(), corpid);
                //
                List<FieldAndLogicPojo> conditionFieldList = getConditionFieldList(paasFormEntity.getName(), paasFormExplainEntity, explainRelyAttrListDTO.getSaasMark(), paasFormEntity.getDistributorMark());
                formExplainListVO.setFormExplainList(conditionFieldList);
                formExplainListVO.setAppId(paasFormExplainEntity.getAppId());
                formExplainListVO.setFormExplainId(paasFormExplainEntity.getId());
                formExplainListVO.setFormId(paasFormExplainEntity.getFormId());
            } else {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
        } catch (XbbException e) {
            throw e;
        }catch (Exception e) {
            LOG.error("paasFormExplain.relyAttrList 获取关联表单字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formExplainListVO;
    }

    private  FieldAndLogicPojo getConditionFieldAndLogic(FieldAttrEntity fieldAttrEntity) throws XbbException{
        if (Objects.equals(1, fieldAttrEntity.getIsOpen()) && Objects.equals(1, fieldAttrEntity.getVisible())
                && (Objects.isNull(fieldAttrEntity.getShowType()) || Objects.equals(0, fieldAttrEntity.getShowType()))
                && Objects.nonNull(FieldConditionEnum.getByCode(fieldAttrEntity.getFieldType()))) {
            Integer fieldType = fieldAttrEntity.getFieldType();
            FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
            if (fieldTypeEnum != null) {

                FieldAndLogicPojo fieldAndLogicPojo = new FieldAndLogicPojo(fieldAttrEntity.getAttr(), fieldType, fieldAttrEntity.getAttrName(), fieldAttrEntity.getVisible(), fieldAttrEntity.getEditable());
                Object object = proFormHelp.getPrivateConst(fieldTypeEnum.getAlias(), ConditionLogicConstant.class);
                List<LogicPojo> logicList = proFormHelp.getLogicList(object, 0);
                // 设置值类型
                fieldAndLogicPojo.setValueTypeList(proFormHelp.getValueTypeList(fieldType));
                // 按照字段类型设置属性
                proFormHelp.setFieldAttr(fieldAttrEntity, fieldAndLogicPojo);
                fieldAndLogicPojo.setLogicList(logicList);
                // 若是关联字段，给前端返回相应关联表单类型
                if (Objects.equals(fieldType, FieldTypeEnum.LINK_BUSINESS_SINGLE.getType())) {
                    fieldAndLogicPojo.setLinkedType(fieldAttrEntity.getLinkedType());
                } else if (Objects.equals(fieldType, FieldTypeEnum.LINK_DATA.getType()) || Objects.equals(fieldType, FieldTypeEnum.LINK_DATA_MULTI.getType())) {
                    fieldAndLogicPojo.setLinkInfo(fieldAttrEntity.getLinkInfo());
                }
                return fieldAndLogicPojo;
            }
        }
        return null;
    }

    /**
     * 封装条件字段
     * @param formName
     * @param paasFormExplainEntity
     * @return
     * @author xingxing.xiao
     * @date 2020/08/07 10:23
     */
    private List<FieldAndLogicPojo> getConditionFieldList (String formName, PaasFormExplainEntity paasFormExplainEntity, Integer saasMark, Integer distributorMark) throws XbbException {
        Integer businessType = paasFormExplainEntity.getBusinessType();
        Long formId = paasFormExplainEntity.getFormId();

        businessType = XbbRefTypeEnum.transferBusinessType4Distributor(businessType,distributorMark);
        List<FieldAndLogicPojo> explainList = new ArrayList<>();
        String attrName = formName + "ID";
        if (Objects.equals(SaasMarkEnum.SAAS.getCode(), saasMark)) {
            RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(businessType);
            attrName = redundantTemplateTypeEnum.getName()+ "ID";
        }
        FieldAndLogicPojo jsonObject = new FieldAndLogicPojo(FieldTypeEnum.DATAID.getAlias(), FieldTypeEnum.DATAID.getType(),  attrName, 1, 0);
        LogicPojo equal = new LogicPojo(ConditionEnum.EQUAL.getMemo(), ConditionEnum.EQUAL.getSymbol());
        LogicPojo noEqual = new LogicPojo(ConditionEnum.NOEQUAL.getMemo(), ConditionEnum.NOEQUAL.getSymbol());
        List<LogicPojo> dataLogicList = new ArrayList<>();
        dataLogicList.add(equal);
        dataLogicList.add(noEqual);
        jsonObject.setValueTypeList(proFormHelp.getValueTypeList(FieldTypeEnum.DATAID.getType()));
        jsonObject.setLogicList(dataLogicList);
        explainList.add(jsonObject);
        List<FieldAttrEntity> fieldList = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        Iterator<FieldAttrEntity> iterator = fieldList.iterator();
        List<FieldAndLogicPojo> conditionFieldList = new ArrayList<>();
        conditionFieldList.addAll(explainList);
        while (iterator.hasNext()) {
            FieldAttrEntity fieldAttrEntity = iterator.next();
            Integer showType = fieldAttrEntity.getShowType();
            Boolean invisible = Objects.nonNull(fieldAttrEntity.getShowType()) && (ShowTypeEnum.LIST.getCode() == showType || ShowTypeEnum.DETAIL.getCode() == showType
                    || ShowTypeEnum.LIST_DETAIL.getCode() == showType || ShowTypeEnum.NONE.getCode() == showType);
            if (invisible || Objects.equals(0, fieldAttrEntity.getIsOpen())) {
                continue;
            }
            Integer fieldType = fieldAttrEntity.getFieldType();
            // 过滤子表单(关联表单不能选择子表单字段)
            if (Objects.equals(FieldTypeEnum.SUB_FORM.getType(), fieldType)) {
                continue;
            }
            FieldAndLogicPojo conditionField = getConditionFieldAndLogic(fieldAttrEntity);
            if (Objects.nonNull(conditionField)) {
                conditionFieldList.add(conditionField);
            }
        }
        return conditionFieldList;
    }

    /**
     * 关联表单可选择字段 - 多模板
     * @param relyBusinessAttrListDTO
     * @return
     * @author xingxing.xiao
     * @date 2020/08/07 10:24
     */
    @Override
    public ExplainRelyBusinessAttrListVO relyBusinessAttrList(ExplainRelyBusinessAttrListDTO relyBusinessAttrListDTO) throws XbbException {
        ExplainRelyBusinessAttrListVO relyAttrListVO = new ExplainRelyBusinessAttrListVO();
        String corpid = relyBusinessAttrListDTO.getCorpid();
        try {
            // 应该不会有工单吧
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("columns", "id, name");
            param.put("corpid", corpid);
            param.put("idIn", relyBusinessAttrListDTO.getFormIds());
            param.put("del", DelEnum.NORMAL.getDel());
            List<PaasFormEntity> formList = paasFormModel.findEntity(param);
            if (formList.isEmpty()) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }

            Map<Long, PaasFormEntity> formNameMap = new HashMap<>();
            formList.forEach(item -> formNameMap.put(item.getId(), item));

            param.clear();
            param.put("corpid", corpid);
            param.put("formIdIn", relyBusinessAttrListDTO.getFormIds());
            param.put("del", DelEnum.NORMAL.getDel());
            List<PaasFormExplainEntity> formExplainList = paasFormExplainModel.findEntitys(param);
            if (formExplainList.isEmpty()) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            List<ExplainRelyAttrListVO> relyAttrList = new ArrayList<>();
            for (PaasFormExplainEntity explainEntity : formExplainList) {
                String formName = formNameMap.get(explainEntity.getFormId()).getName();
                Integer distributorMark = formNameMap.get(explainEntity.getFormId()).getDistributorMark();
                List<FieldAndLogicPojo> conditionFieldList = getConditionFieldList(formName, explainEntity, relyBusinessAttrListDTO.getSaasMark(), distributorMark);
                ExplainRelyAttrListVO explainRelyAttrListVO = new ExplainRelyAttrListVO();
                explainRelyAttrListVO.setFormExplainList(conditionFieldList);
                explainRelyAttrListVO.setAppId(explainEntity.getAppId());
                explainRelyAttrListVO.setFormExplainId(explainEntity.getId());
                explainRelyAttrListVO.setFormId(explainEntity.getFormId());
                relyAttrList.add(explainRelyAttrListVO);
            }
            relyAttrListVO.setRelyAttrList(relyAttrList);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormExplain.relyBusinessAttrList 获取关联表单字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return relyAttrListVO;
    }

    /**
     * 关联表单可选择字段
     * @param explainRelationListDTO
     * @return
     * @author xingxing.xiao
     * @date 2020/07/29 15:15
     */
    @Override
    public ExplainRelationListVO relationAttrList(ExplainRelationListDTO explainRelationListDTO) throws XbbException {
        ExplainRelationListVO explainRelationListVO = new ExplainRelationListVO();
        try {
            FilterExplainByRuleDTO filterExplainByRuleDTO = new FilterExplainByRuleDTO();
            BeanUtil.copyProperties(explainRelationListDTO, filterExplainByRuleDTO);
            List<Integer> blockType = Arrays.asList(FieldTypeEnum.DATETIME.getType());
            Integer fieldType = explainRelationListDTO.getFieldType();
            boolean block = blockType.contains(fieldType);
            // 过滤字段
            List<FieldAttrEntity> jsonArray = getFieldListByRelation(new FieldRelyConstant(), filterExplainByRuleDTO, fieldType, block);
            // 添加数据id作为条
            formExplainHelp.addDataIdAsCondition(jsonArray, explainRelationListDTO.getFieldType(), filterExplainByRuleDTO, true);
            explainRelationListVO.setFormExplainList(jsonArray);
            explainRelationListVO.setAppId(explainRelationListDTO.getAppId());
            explainRelationListVO.setMenuId(explainRelationListDTO.getMenuId());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormExplain.relationAttrList 出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return explainRelationListVO;
    }

    /**
     * 过滤字段
     * @param clazz
     * @param filterExplainByRuleDTO
     * @param fieldType
     * @param block
     * @author xingxing.xiao
     */
    public List<FieldAttrEntity> getFieldListByRelation(Object clazz, FilterExplainByRuleDTO filterExplainByRuleDTO, Integer fieldType, boolean block) throws XbbException {
        List<FieldAttrEntity> jsonArray = new ArrayList<>();
        try {
            List<FieldAttrEntity> explainJsonArray;
            String corpid = filterExplainByRuleDTO.getCorpid();
            Long formId = filterExplainByRuleDTO.getFormId();
            Integer businessType = filterExplainByRuleDTO.getBusinessType();
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), businessType)) {
                WorkOrderExplainEntityExt workOrderExplainEntityExt = workOrderExplainModel.getByFormId(formId, corpid);
                if (workOrderExplainEntityExt == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                }
                explainJsonArray = JSON.parseArray(workOrderExplainEntityExt.getExplains(), FieldAttrEntity.class);
            } else {
                PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
                if (paasFormExplainEntity == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                }
                explainJsonArray = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            }
            FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
            String alias = fieldTypeEnum.getAlias().toUpperCase();
            Set<Integer> fieldTypeSet = new HashSet<>();
            if (fieldTypeEnum != null && ReflectHelper.exist(clazz, alias)) {
                Integer[] array = (Integer[]) ReflectHelper.valueGet(clazz, alias);
                for (Integer integer : array) {
                    fieldTypeSet.add(integer);
                }
            }
            for (FieldAttrEntity fieldAttrEntity : explainJsonArray) {
                Integer showType = fieldAttrEntity.getShowType();
                Boolean invisible = Objects.nonNull(fieldAttrEntity.getShowType()) && (ShowTypeEnum.LIST.getCode() == showType || ShowTypeEnum.DETAIL.getCode() == showType
                        || ShowTypeEnum.LIST_DETAIL.getCode() == showType || ShowTypeEnum.NONE.getCode() == showType);
                if (invisible || Objects.equals(0, fieldAttrEntity.getIsOpen())) {
                    continue;
                }
                if (Objects.equals(FieldTypeEnum.SUB_FORM.getType(), fieldAttrEntity.getFieldType())) {
                    List<? extends FieldAttrEntity> subFieldList = fieldAttrEntity.getSubForm().getItems();
                    subFieldList.forEach(item->{
                        if (fieldTypeSet.contains(item.getFieldType())) {
                            item.setAttrName(fieldAttrEntity.getAttrName() + "." + item.getAttrName());
                            item.setAttr(fieldAttrEntity.getAttr() + "." +item.getAttr());
                            jsonArray.add(item);
                        }
                    });
                } else if (fieldTypeSet.contains(fieldAttrEntity.getFieldType())) {
                    jsonArray.add(fieldAttrEntity);
                }
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormExplainServiceImpl根据规则过滤字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return jsonArray;
    }

    @Override
    public RuleFormExplainListVO ruleList(FormExplainListDTO formExplainListDTO) throws XbbException {
        RuleFormExplainListVO formExplainListVO = new RuleFormExplainListVO();
        try {
            String corpid = formExplainListDTO.getCorpid();
            PaasFormExplainEntity paasFormExplainEntity = proFormHelp.getExplainEntity(corpid, formExplainListDTO.getFormId(), formExplainListDTO.getBusinessType());

            Map<Integer, List<String>> fieldBlockMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            fieldBlockMap.put(XbbRefTypeEnum.PAYMENT_SHEET.getCode(), Arrays.asList(PaymentSheetEnum.PAY_METHOD.getAttr(), PaymentSheetEnum.FUND_ACCOUNT.getAttr()));
            if(paasFormExplainEntity != null ) {
                Integer businessType = paasFormExplainEntity.getBusinessType();
                if (Objects.isNull(businessType)) {
                    // 工单的特殊处理
                    businessType = formExplainListDTO.getBusinessType();
                }
                List<FieldAndLogicPojo> explainList = new ArrayList<>();
                FieldAndLogicPojo jsonObject = new FieldAndLogicPojo(FieldTypeEnum.DATAID.getAlias(), FieldTypeEnum.DATAID.getType(),  FieldTypeEnum.DATAID.getDescription(), 1, 0);
                LogicPojo equal = new LogicPojo(ConditionEnum.EQUAL.getMemo(), ConditionEnum.EQUAL.getSymbol());
                LogicPojo noEqual = new LogicPojo(ConditionEnum.NOEQUAL.getMemo(), ConditionEnum.NOEQUAL.getSymbol());
                List<LogicPojo> dataLogicList = new ArrayList<>();
                dataLogicList.add(equal);
                dataLogicList.add(noEqual);
                jsonObject.setValueTypeList(proFormHelp.getValueTypeList(FieldTypeEnum.DATAID.getType()));
                jsonObject.setLogicList(dataLogicList);
                explainList.add(jsonObject);
                List<FieldAttrEntity> fieldList = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                Iterator<FieldAttrEntity> iterator = fieldList.iterator();
                List<FieldAndLogicPojo> conditionFieldList = new ArrayList<>();
                List<FieldAndLogicPojo> operatorFieldList = new ArrayList<>();
                conditionFieldList.addAll(explainList);
                while (iterator.hasNext()) {
                    // 过滤掉非自定义字段和子表单
                    FieldAttrEntity fieldAttrEntity = iterator.next();
                    Integer fieldType = fieldAttrEntity.getFieldType();
                    if (fieldBlockMap.containsKey(businessType)) {
                        List<String> fieldBlockList = fieldBlockMap.get(businessType);
                        if (fieldBlockList.contains(fieldAttrEntity.getAttr())) {
                            continue;
                        }
                    }
                    if (Objects.equals(FieldTypeEnum.SUB_FORM.getType(), fieldType)) {
                        List<? extends FieldAttrEntity> subFieldList = fieldAttrEntity.getSubForm().getItems();
                        for (FieldAttrEntity subField : subFieldList) {
                            FieldAndLogicPojo operatorField = proFormHelp.getOperatorObject(subField, businessType, OperateLogicConstant.class);
                            FieldAndLogicPojo conditionField = getFieldAndLogic(subField, businessType);
                            if (Objects.nonNull(operatorField)) {
                                operatorField.setAttr(fieldAttrEntity.getAttr()+ "."+ subField.getAttr());
                                operatorField.setAttrName(fieldAttrEntity.getAttrName()+ "."+ subField.getAttrName());
                                operatorFieldList.add(operatorField);
                            }
                            if (Objects.nonNull(conditionField)){
                                conditionField.setAttr(fieldAttrEntity.getAttr()+ "."+ subField.getAttr());
                                conditionField.setAttrName(fieldAttrEntity.getAttrName()+ "."+ subField.getAttrName());
                                conditionFieldList.add(conditionField);
                            }

                        }
                    } else {
                        // 操作方式
                        FieldAndLogicPojo operatorField = proFormHelp.getOperatorObject(fieldAttrEntity, businessType, OperateLogicConstant.class);
                        // 过滤条件
                        FieldAndLogicPojo conditionField = getFieldAndLogic(fieldAttrEntity, businessType);
                        if (Objects.nonNull(operatorField)) {
                            operatorFieldList.add(operatorField);
                        }
                        if (Objects.nonNull(conditionField)) {
                            conditionFieldList.add(conditionField);
                        }
                    }
                }
                formExplainListVO.setFormExplainList(conditionFieldList);
                formExplainListVO.setOperatorFieldList(operatorFieldList);
                formExplainListVO.setAppId(paasFormExplainEntity.getAppId());
                formExplainListVO.setFormExplainId(paasFormExplainEntity.getFormId());
                formExplainListVO.setFormId(paasFormExplainEntity.getFormId());
            } else {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
        } catch (XbbException e) {
            throw e;
        }catch (Exception e) {
            LOG.error("paasFormExplain.ruleList数据库搜索表单规则字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formExplainListVO;
    }


    private  FieldAndLogicPojo getFieldAndLogic(FieldAttrEntity fieldAttrEntity, Integer businessType) throws XbbException{
        // 开启、可见及业务规则可作条件字段
        boolean flag = Objects.equals(1, fieldAttrEntity.getIsOpen()) && Objects.equals(1, fieldAttrEntity.getVisible()) && Objects.nonNull(RuleConditionFieldEnum.getByCode(fieldAttrEntity.getFieldType()));
        // 系统字段
        JSONArray attrArray = RuleConditionBusinessFieldEnum.getAttrsByCode(businessType);
        boolean sysFlag = Objects.equals(fieldAttrEntity.getIsRedundant(), BasicConstant.ZERO) && attrArray.contains(fieldAttrEntity.getAttr());
        // 自定义字段
        boolean cusFlag = Objects.equals(fieldAttrEntity.getIsRedundant(), BasicConstant.ONE) && (Objects.isNull(fieldAttrEntity.getShowType()) || Objects.equals(0, fieldAttrEntity.getShowType()));

        if (flag && (sysFlag || cusFlag)) {
            Integer fieldType = fieldAttrEntity.getFieldType();
            FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
            if (fieldTypeEnum != null) {

                FieldAndLogicPojo fieldAndLogicPojo = new FieldAndLogicPojo(fieldAttrEntity.getAttr(), fieldType, fieldAttrEntity.getAttrName(), fieldAttrEntity.getVisible(), fieldAttrEntity.getEditable());
                Object object = proFormHelp.getPrivateConst(fieldTypeEnum.getAlias(), ConditionLogicConstant.class);
                List<LogicPojo> logicList = proFormHelp.getLogicList(object, 0);
                // 设置值类型
                fieldAndLogicPojo.setValueTypeList(proFormHelp.getValueTypeList(fieldType));
                // 按照字段类型设置属性
                proFormHelp.setFieldAttr(fieldAttrEntity, fieldAndLogicPojo);
                fieldAndLogicPojo.setLogicList(logicList);
                return fieldAndLogicPojo;
            }
        }
        return null;
    }

    /**
     * 获取过滤条件以及逻辑字符
     * @param fieldAttrEntity
     * @param list
     * @return
     * @throws XbbException
     */
    private  FieldAndLogicPojo getFilterConditionFieldAndLogic(FieldAttrEntity fieldAttrEntity, List<String> list) throws XbbException{
        // 开启、可见及业务规则可作条件字段
        RuleFilterConditionEnum ruleFilterConditionEnum = RuleFilterConditionEnum.getByCode(fieldAttrEntity.getFieldType());
        boolean flag = Objects.equals(1, fieldAttrEntity.getIsOpen()) && Objects.equals(1, fieldAttrEntity.getVisible()) && Objects.nonNull(ruleFilterConditionEnum);
        // 自定义字段
        boolean cusFlag = (Objects.isNull(fieldAttrEntity.getShowType()) || Objects.equals(0, fieldAttrEntity.getShowType()));

        boolean isTrue = (flag && cusFlag) || (list.contains(fieldAttrEntity.getAttr()) && Objects.equals(0, fieldAttrEntity.getIsRedundant()));
        if (isTrue) {
            Integer fieldType = fieldAttrEntity.getFieldType();
            FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
            if (fieldTypeEnum != null) {

                FieldAndLogicPojo fieldAndLogicPojo = new FieldAndLogicPojo(fieldAttrEntity.getAttr(), fieldType, fieldAttrEntity.getAttrName(), fieldAttrEntity.getVisible(),
                        fieldAttrEntity.getEditable(), fieldAttrEntity.getSaasParticularAttributePoJo());
                List<LogicPojo> logicList = proFormHelp.getLogicList(ruleFilterConditionEnum.getLoginList(), 0);
                // 设置值类型
                // 按照字段类型设置属性
                proFormHelp.setFieldAttr(fieldAttrEntity, fieldAndLogicPojo);
                fieldAndLogicPojo.setLogicList(logicList);
                return fieldAndLogicPojo;
            }
        }
        return null;
    }

    /**
     * 获取成员、部门筛选可选范围过滤条件以及逻辑字符
     * @param fieldAttrEntity
     * @return
     * @throws XbbException
     */
    private  FieldAndLogicPojo getOptionalFieldAndLogic(FieldAttrEntity fieldAttrEntity) throws XbbException{
        OptionalRangeFieldEnum optionalRangeEnum = OptionalRangeFieldEnum.getByCode(fieldAttrEntity.getFieldType());
        Integer fieldType = fieldAttrEntity.getFieldType();
        FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
        if (Objects.nonNull(fieldTypeEnum)) {
            FieldAndLogicPojo fieldAndLogicPojo = new FieldAndLogicPojo(fieldAttrEntity.getAttr(), fieldType, fieldAttrEntity.getAttrName(), fieldAttrEntity.getVisible(),
                    fieldAttrEntity.getEditable(), fieldAttrEntity.getSaasParticularAttributePoJo());
            List<LogicPojo> logicList = proFormHelp.getLogicList(optionalRangeEnum.getLoginList(), 0);
            // 设置值类型
            // 按照字段类型设置属性
            fieldAndLogicPojo.setLogicList(logicList);
            //设置动态值和固定值
            List<ValueTypePojo> valueTypePojoList = new ArrayList<>();
            if (Objects.equals(FieldTypeEnum.ROLE_NAME.getType(), fieldAttrEntity.getFieldType() )){
                valueTypePojoList.add(new ValueTypePojo(RuleValueTypeEnum.FIXED_VALUE.getType(), RuleValueTypeEnum.FIXED_VALUE.getName()));
                fieldAndLogicPojo.setEditable(1);
                fieldAndLogicPojo.setComboType(0);
            } else{
                valueTypePojoList.add(new ValueTypePojo(RuleValueTypeEnum.DYNAMIC_VALUE.getType(), RuleValueTypeEnum.DYNAMIC_VALUE.getName()));
                valueTypePojoList.add(new ValueTypePojo(RuleValueTypeEnum.FIXED_VALUE.getType(), RuleValueTypeEnum.FIXED_VALUE.getName()));
            }
            fieldAndLogicPojo.setValueTypeList(valueTypePojoList);
            return fieldAndLogicPojo;
        }
        return null;
    }

    @Override
    public ExplainRelationListVO relationRuleList(ExplainRelationListDTO explainRelationListDTO) throws XbbException {
        ExplainRelationListVO explainRelationListVO = new ExplainRelationListVO();
        try {
            FilterExplainByRuleDTO filterExplainByRuleDTO = new FilterExplainByRuleDTO();
            BeanUtil.copyProperties(explainRelationListDTO, filterExplainByRuleDTO);
            List<Integer> blockType = Arrays.asList(FieldTypeEnum.DATETIME.getType());
            Integer fieldType = explainRelationListDTO.getFieldType();
            boolean block = blockType.contains(fieldType);
            List<FieldAttrEntity> jsonArray = getFieldListByRuleIncludeSubField(new RuleFieldRelationConstant(), filterExplainByRuleDTO, fieldType, block, true);
            formExplainHelp.addDataIdAsCondition(jsonArray, explainRelationListDTO.getFieldType(), filterExplainByRuleDTO, false);
            explainRelationListVO.setFormExplainList(jsonArray);
            explainRelationListVO.setAppId(explainRelationListDTO.getAppId());
            explainRelationListVO.setMenuId(explainRelationListDTO.getMenuId());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormExplain.relationRuleList出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return explainRelationListVO;
    }

    @Override
    public ExplainOperatorVO operatorRuleList(ExplainOperatorDTO explainOperatorDTO) throws XbbException {
        ExplainOperatorVO explainOperatorVO = new ExplainOperatorVO();
        try {
            FilterExplainByRuleDTO filterExplainByRuleDTO = new FilterExplainByRuleDTO();
            BeanUtil.copyProperties(explainOperatorDTO, filterExplainByRuleDTO);
            List<FieldAttrEntity> explainList;
            if (Objects.isNull(explainOperatorDTO.getType()) || Objects.equals(RuleVersionEnum.SIMPLE.getType(), explainOperatorDTO.getType())) {
                // 基础版本
                explainList = getFieldListByRuleIncludeSubField(new RuleFieldOperatorConstant(), filterExplainByRuleDTO, explainOperatorDTO.getFieldType(), false, false);
            } else {
                // 高级版本
                explainList = getFieldListByRuleIncludeSubField(new AdvancedRuleFieldOperatorConstant(), filterExplainByRuleDTO, explainOperatorDTO.getFieldType(), false, false);
            }
            formExplainHelp.addDataIdInBusinessRule(explainList, explainOperatorDTO.getFieldType(), filterExplainByRuleDTO.getFormId(), filterExplainByRuleDTO.getBusinessType(),
                    filterExplainByRuleDTO.getLinkInfo());
            explainOperatorVO.setFormExplainList(explainList);
            explainOperatorVO.setAppId(explainOperatorDTO.getAppId());
            explainOperatorVO.setMenuId(explainOperatorDTO.getMenuId());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormExplain.operatorRuleList 出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return explainOperatorVO;
    }

    @Override
    public PartFormExplainListVO partExplainList(PartFormExplainListDTO formExplainListDTO) throws XbbException {
        PartFormExplainListVO partFormExplainListVO = new PartFormExplainListVO();
        try {
            Map<String, Object> param = BeanUtil.convertBean2Map(formExplainListDTO, true);
            List<PaasFormExplainEntity> list = paasFormExplainModel.list(param);
            if (list == null || list.isEmpty()) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            PaasFormExplainEntity paasFormExplainEntity = list.get(0);
            JSONArray resultJSONArray = new JSONArray();
            JSONArray explainJSONArray = JSON.parseArray(paasFormExplainEntity.getExplains());
            for (Object object : explainJSONArray) {
                JSONObject jsonObject = (JSONObject) object;
                Integer fieldType = jsonObject.getInteger("fieldType");
                if (LinkConditionNeedFilterFieldEnum.getFieldTypeEnum(fieldType) == null) {
                    resultJSONArray.add(jsonObject);
                }
            }
            partFormExplainListVO.setFormExplainList(resultJSONArray);
            partFormExplainListVO.setAppId(paasFormExplainEntity.getAppId());
            partFormExplainListVO.setFormExplainId(paasFormExplainEntity.getFormId());
            partFormExplainListVO.setFormId(paasFormExplainEntity.getFormId());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormExplain数据库搜索表单字段后过滤字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return partFormExplainListVO;
    }

    @Override
    public LinkExplainListVO list(LinkExplainListDTO linkExplainListDTO) throws XbbException {
        LinkExplainListVO linkExplainListVO = new LinkExplainListVO();
        try {
            String corpid = linkExplainListDTO.getCorpid();
            PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), linkExplainListDTO.getBusinessType())) {
                // 工单逻辑
                WorkOrderExplainEntityExt workOrderExplainEntityExt = workOrderExplainModel.getByFormId(linkExplainListDTO.getFormId(), corpid);
                if (Objects.isNull(workOrderExplainEntityExt)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                if (workOrderExplainEntityExt == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                }
                BeanUtil.copyProperties(workOrderExplainEntityExt, paasFormExplainEntity);
            } else {
                paasFormExplainEntity = paasFormExplainModel.getByFormId(linkExplainListDTO.getFormId(), corpid);
            }
            if (paasFormExplainEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            List<FieldAttrEntity> explainJSONArray = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            Iterator<FieldAttrEntity> iterator = explainJSONArray.iterator();
            while (iterator.hasNext()) {
                FieldAttrEntity jsonObject = iterator.next();
                Integer fieldType = jsonObject.getFieldType();
                if (Objects.isNull(LinkFieldDisplayEnum.getFieldTypeEnum(fieldType))) {
                    iterator.remove();
                }
            }
            linkExplainListVO.setFormExplainList(explainJSONArray);
            linkExplainListVO.setAppId(paasFormExplainEntity.getAppId());
            linkExplainListVO.setFormExplainId(paasFormExplainEntity.getFormId());
            linkExplainListVO.setFormId(paasFormExplainEntity.getFormId());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormExplain数据库搜索关联数据或者关联查询的关联表的关联字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return linkExplainListVO;
    }

    @Override
    public LinkCompareFieldVO linkCompareList(LinkCompareFieldDTO linkCompareFieldDTO) throws XbbException {
        LinkCompareFieldVO linkCompareFieldVO = new LinkCompareFieldVO();
        try {
            FilterExplainByRuleDTO filterExplainByRuleDTO = new FilterExplainByRuleDTO();
            BeanUtil.copyProperties(linkCompareFieldDTO, filterExplainByRuleDTO);
            List<FieldAttrEntity> jsonArray = getFilterExplainListByRule(new LinkCompareConstant(), filterExplainByRuleDTO, linkCompareFieldDTO.getFieldType());
            // 添加数据id作为条件
            formExplainHelp.addDataIdAsCondition(jsonArray, linkCompareFieldDTO.getFieldType(), filterExplainByRuleDTO, true);
            // 入库单、出库单不需要返回系统关联字段
            removeLinkBusiness(jsonArray, linkCompareFieldDTO.getFieldType(), linkCompareFieldDTO.getBusinessType());
            linkCompareFieldVO.setFormExplainList(jsonArray);
            linkCompareFieldVO.setAppId(linkCompareFieldDTO.getAppId());
            linkCompareFieldVO.setMenuId(linkCompareFieldDTO.getMenuId());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormExplain数据库获取默认值-数据联动-联动表单的比较字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return linkCompareFieldVO;
    }

    @Override
    public LinkDisplayFieldVO linkDisplayFieldList(LinkDisplayFieldDTO linkDisplayFieldDTO) throws XbbException {
        LinkDisplayFieldVO linkDisplayFieldVO = new LinkDisplayFieldVO();
        try {
            FilterExplainByRuleDTO filterExplainByRuleDTO = new FilterExplainByRuleDTO();
            BeanUtil.copyProperties(linkDisplayFieldDTO, filterExplainByRuleDTO);
            List<FieldAttrEntity> jsonArray = getFilterExplainListByRule(new LinkDisplayConstant(), filterExplainByRuleDTO, linkDisplayFieldDTO.getFieldType());
            linkDisplayFieldVO.setFormExplainList(jsonArray);
            linkDisplayFieldVO.setAppId(linkDisplayFieldDTO.getAppId());
            linkDisplayFieldVO.setMenuId(linkDisplayFieldDTO.getMenuId());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormExplain数据库搜索获取默认值-数据联动-联动表单的显示字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return linkDisplayFieldVO;
    }

    @Override
    public LinkDisplayFieldVO linkConvertFieldList(LinkDisplayFieldDTO linkDisplayFieldDTO) throws XbbException {
        LinkDisplayFieldVO linkDisplayFieldVO = new LinkDisplayFieldVO();
        try {
            FilterExplainByRuleDTO filterExplainByRuleDTO = new FilterExplainByRuleDTO();
            BeanUtil.copyProperties(linkDisplayFieldDTO, filterExplainByRuleDTO);
            filterExplainByRuleDTO.setLinkAttr(linkDisplayFieldDTO.getAttr());
            List<FieldAttrEntity> jsonArray = getConvertFilterExplainListByRule(new LinkDisplayConstant(), filterExplainByRuleDTO, linkDisplayFieldDTO.getFieldType());
            linkDisplayFieldVO.setFormExplainList(jsonArray);
            linkDisplayFieldVO.setAppId(linkDisplayFieldDTO.getAppId());
            linkDisplayFieldVO.setMenuId(linkDisplayFieldDTO.getMenuId());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormExplain数据库搜索获取默认值-数据联动-联动表单的显示字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return linkDisplayFieldVO;
    }

    /**
     * 获取关联新建的解释和数据
     *
     * @param linkFormItemDTO 关联新建入参
     * @return com.xbongbong.pro.formexplain.pojo.vo.LinkFormItemVO
     * @throws XbbException 业务异常
     * @author feng.zheng
     * @date 2019/2/20 19:29
     */
    @Override
    public LinkFormItemVO linkFormList(LinkFormItemDTO linkFormItemDTO) throws XbbException {
        LinkFormItemVO linkFormItemVO = new LinkFormItemVO();
        String corpid = linkFormItemDTO.getCorpid();
        Integer linkBusinessType = linkFormItemDTO.getLinkBusinessType();
        Integer businessType = linkFormItemDTO.getBusinessType();
        Long dataId = linkFormItemDTO.getDataId();
        Long taskId = linkFormItemDTO.getTaskId();
        SheetTypeEnum sheetTypeEnum = SheetTypeEnum.getByBusinessType(linkBusinessType);
        boolean sheetFlag = SheetTypeEnum.validateSheet(sheetTypeEnum);
        boolean paymentSheetFlag = PaymentSheetTypeEnum.validateSheet(sheetTypeEnum);
        boolean paySheetFlag = PaySheetTypeEnum.validateSheet(sheetTypeEnum);
        Integer distributorMark = linkFormItemDTO.getDistributorMark();
        List<String> paymentSheetTypeList = null;
        List<String> paySheetTypeList = null;
        PaasFormEntityExt linkForm;
        if (paymentSheetFlag) {
            if (Objects.equals(sheetTypeEnum, SheetTypeEnum.WRITE_OFF)) {
                paymentSheetTypeList = Arrays.asList(SheetTypeEnum.WRITE_OFF.getCode(), PaymentSheetTypeEnum.RED_WRITE_OFF.getCode(), PaymentSheetTypeEnum.BAD_PAYMENT.getCode());
            } else if (Objects.equals(sheetTypeEnum, SheetTypeEnum.WRITE_OFF_PREPAYMENT)) {
                paymentSheetTypeList = Arrays.asList(PaymentSheetTypeEnum.WRITE_OFF_PREPAYMENT.getCode(), PaymentSheetTypeEnum.RED_WRITE_OFF_PREPAYMENT.getCode(), PaymentSheetTypeEnum.RED_WRITE_OFF_BALANCE.getCode());
            }
            linkForm = paasFormModel.getByBusinessType4Distributor(XbbRefTypeEnum.PAYMENT_SHEET.getCode(), corpid, distributorMark, null);
        } else if ( paySheetFlag ) {
            if (Objects.equals(sheetTypeEnum, SheetTypeEnum.WRITE_OFF_PAY)) {
                paySheetTypeList = Arrays.asList(PaySheetTypeEnum.WRITE_OFF_PAY.getCode(), PaySheetTypeEnum.RED_WRITE_OFF_PAY.getCode(), PaySheetTypeEnum.BAD_PAY.getCode());
            } else if (Objects.equals(sheetTypeEnum, SheetTypeEnum.WRITE_OFF_PREPAY)) {
                paySheetTypeList = Arrays.asList(PaySheetTypeEnum.WRITE_OFF_PREPAY.getCode(), PaySheetTypeEnum.RED_WRITE_OFF_PREPAY.getCode());
            }
            linkForm = paasFormModel.getByBusinessType(XbbRefTypeEnum.PAY_SHEET.getCode(), corpid);
        } else if (sheetFlag) {
            //其他收入单、其他支出单
            linkForm = paasFormModel.getByBusinessType(sheetTypeEnum.getXbbRefTypeEnum().getCode(), corpid);
        } else if (Objects.equals(distributorMark, DistributorMarkEnum.DISTRIBUTOR.getCode())) { // 经销商
            linkForm = paasFormModel.getByBusinessType4Distributor(linkBusinessType, corpid, distributorMark, null);
        } else {
            linkForm = paasFormModel.getByBusinessType(linkBusinessType, corpid);
        }
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(linkForm.getId(), corpid);
        Long appId = paasFormExplainEntity.getAppId();
        Long menuId = paasFormExplainEntity.getMenuId();
        Long formId = paasFormExplainEntity.getFormId();
        saasAddHelp.handleFormEntity(linkForm, linkFormItemDTO.getSaasMark(), linkFormItemDTO.getBusinessType());
        String formName = linkForm.getName();
        RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(businessType);
        FormDataListDTO formDataListDTO = new FormDataListDTO();
        BeanUtil.copyProperties(linkFormItemDTO, formDataListDTO);
        formDataListDTO.setAppId(appId);
        formDataListDTO.setMenuId(menuId);
        formDataListDTO.setBusinessType(linkBusinessType);
        List<PaasFormDataEntityExt> formDataList = new ArrayList<>();
        List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        boolean editFlag = dataId != null && !Objects.equals(dataId, 0L);
        SaasSpecialParamPojo saasSpecialParamPojo = linkFormItemDTO.getSaasSpecialParamPojo();
        //关联新建红冲发票特殊处理
        if (Objects.equals(XbbRefTypeEnum.INVOICE.getCode(), linkBusinessType)) {
            if (saasSpecialParamPojo != null && Objects.equals(IsRedEnum.RED.getCode(), saasSpecialParamPojo.getFromRed())) {
                linkFormHandleRedInvoiceExplain(explainList);
                //关联新建红冲发票不走流程获取字段解释
                linkForm.setIsProcessForm(BasicConstant.ZERO);
            }
        }else if (Objects.equals(XbbRefTypeEnum.PAYMENT.getCode(), businessType) &&
                    Objects.equals(XbbRefTypeEnum.PAYMENT.getCode(), linkBusinessType) &&
                        !editFlag) {
            //需要把应收款中的来源单据移除掉,解决移动端合同那边新增应收款显示来源单据
            handPaymentAddExplain(explainList);
        }
        // 过滤下不可见字段
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(linkFormItemDTO, handlerExplainDTO, false);
        handlerExplainDTO.setExplainList(explainList);
        handlerExplainDTO.setPaasFormEntityExt(linkForm);
        HandlerExplainVO handlerExplainVO = formDataAddFormExplainHandlerName.handleExplain(handlerExplainDTO);
        if (handlerExplainVO == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
        }
        explainList = handlerExplainVO.getHeadList();
        if (sheetFlag) {
            fundHelp.handlePaymentSheet(!editFlag, sheetTypeEnum, explainList, corpid, distributorMark);
        }
        RedundantTemplateTypeEnum linkTypeEnum = RedundantTemplateTypeEnum.getByCode(linkBusinessType);
        XbbRefTypeEnum linkXbbRefTypeEnum = XbbRefTypeEnum.getByCode(linkBusinessType);
        analysisExplain(linkTypeEnum, explainList, formDataListDTO);
        List<FieldAttrEntity> showColumnList = getShowColumnList(redundantTemplateTypeEnum, explainList, formDataListDTO, dataId, linkXbbRefTypeEnum);
        Long formDataId = 0L;
        JSONObject dataObject = new JSONObject();
        Long addTime = null;
        if (taskId != null && !Objects.equals(taskId, 0L)) {
            PaasProcessDataEntity paasProcessDataEntity = paasProcessDataModel.getByTaskId(taskId, corpid);
            if (paasProcessDataEntity != null) {
                addTime = paasProcessDataEntity.getAddTime();
                formDataId = paasProcessDataEntity.getFormDataId();
                dataObject = JSONObject.parseObject(paasProcessDataEntity.getData());
                XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(linkFormItemDTO.getBusinessType());
                JSONArray linkArray = new JSONArray();
                String attr = "";
                switch (xbbRefTypeEnum) {
                    case CONTRACT:
                    	switch (linkXbbRefTypeEnum){
		                    case PAYMENT_SHEET:
                                attr = ContractEnum.ADD_PAYMENT_SHEET.getAttr();
		                    	break;
		                    case WRITE_OFF_PREPAYMENT:
                                attr = ContractEnum.ADD_WRITE_OFF_PREPAYMENT.getAttr();
		                    	break;
                            case PAYMENT:
                                attr = ContractEnum.ADD_PAYMENT.getAttr();
                                break;
                            default:
                                break;
                        }
                    break;
                    case PURCHASE:
                        switch (linkXbbRefTypeEnum){
                            case PAY_SHEET:
                                attr = PurchaseEnum.ADD_PAY_SHEET.getAttr();
                                break;
                            case WRITE_OFF_PREPAY:
                                attr = PurchaseEnum.ADD_WRITE_OFF_PREPAY.getAttr();
                                break;
                            case PAY_PLAN:
                                attr = PurchaseEnum.ADD_PAYPLAN.getAttr();
                                break;
                            default:
                                break;
                        }
                        break;
                    case CUSTOMER_MANAGEMENT:
                        attr = CustomerManagementEnum.ADD_CONTACT.getAttr();
                        break;
                    case SUPPLIER:
                        attr = SupplierEnum.ADD_SUPPLIER_CONTACT.getAttr();
                        break;
                    default:
                        break;
                }
                linkArray = dataObject.getJSONArray(attr);
                if (linkArray != null) {
                    //目前只处理回款、付款的业务（资金相关），目前存在合同或者采购合同重新进审批的时候，合同下的回款单、回款计划/采购合同下的付款单、付款计划，已经被删了，但是审批里面还有数据，现在就是需要移除
                    handProcessShouldRemoveValue(corpid, xbbRefTypeEnum, linkXbbRefTypeEnum, linkArray);
                    formDataList = JSON.parseArray(JSON.toJSONString(linkArray), PaasFormDataEntityExt.class);
                    checkDataHavaEditAndDelPermission(formDataList, linkBusinessType, linkFormItemDTO, true);
                }
            }
        } else if (editFlag) {
            if (paymentSheetFlag && Objects.nonNull(paymentSheetTypeList)) {
                List<Object> typeList = new ArrayList<>(paymentSheetTypeList);
                ConditionsEntityExt conditions = new ConditionsEntityExt(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr(), null, FieldTypeEnum.TEXT.getType(), ConditionEnum.IN.getSymbol(), typeList);
                formDataListDTO.getConditions().add(conditions);
                ConditionsEntityExt aloneConditions = new ConditionsEntityExt(FieldTypeEnum.SHEET_ALONE.getAlias(), null, FieldTypeEnum.SHEET_ALONE.getType(), ConditionEnum.IN.getSymbol(), Arrays.asList(SheetAloneEnum.NORMAL.getCode(), SheetAloneEnum.PARENT.getCode()));
                formDataListDTO.getConditions().add(aloneConditions);
            } else if (paySheetFlag && Objects.nonNull(paySheetTypeList)){
                List<Object> typeList = new ArrayList<>(paySheetTypeList);
                ConditionsEntityExt conditions = new ConditionsEntityExt(PaySheetEnum.PAY_SHEET_TYPE.getAttr(), null, FieldTypeEnum.TEXT.getType(), ConditionEnum.IN.getSymbol(), typeList);
                formDataListDTO.getConditions().add(conditions);
                ConditionsEntityExt aloneConditions = new ConditionsEntityExt(FieldTypeEnum.SHEET_ALONE.getAlias(), null, FieldTypeEnum.SHEET_ALONE.getType(), ConditionEnum.IN.getSymbol(), Arrays.asList(SheetAloneEnum.NORMAL.getCode(), SheetAloneEnum.PARENT.getCode()));
                formDataListDTO.getConditions().add(aloneConditions);
            }
            if( Objects.equals(linkXbbRefTypeEnum, XbbRefTypeEnum.PAYMENT) && formDataListDTO.getSortMap().isEmpty()){
                Map<String,String> sortMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                sortMap.put("field", PaymentEnum.ESTIMATE_TIME.getAttr());
                sortMap.put("sort","asc");
                formDataListDTO.setSortMap(sortMap);
            } else if (  Objects.equals(linkXbbRefTypeEnum, XbbRefTypeEnum.PAY_PLAN) && formDataListDTO.getSortMap().isEmpty() ) {
                Map<String,String> sortMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                sortMap.put("field", PayPlanEnum.ESTIMATE_TIME.getAttr());
                sortMap.put("sort","asc");
                formDataListDTO.setSortMap(sortMap);
            }
            formDataListDTO.setDel(DelEnum.NORMAL.getDel());
            // 不要解析的数据
            formDataListDTO.setFromExport(1);
            formDataListDTO.setSearchSubForm(true);
            //采购合同查询关联付款单时防止数据查询不完整
            if (Objects.equals(XbbRefTypeEnum.PURCHASE.getCode(),businessType)){
                formDataListDTO.setPageSize(50);
            }
            PaasFormDataEsListVO formDataEsListVO = paasFormDataService.listByEs(formDataListDTO);
            // 只存数据库未存es数据处理
            saasListHelp.setOnlyDBData(formDataListDTO, formDataEsListVO);
            formDataList = formDataEsListVO.getPaasFormDataESList();
            checkDataHavaEditAndDelPermission(formDataList, linkBusinessType, linkFormItemDTO, false);
        }
        // 获取用户容器
        Map<String, Object> params = BeanUtil.convertBean2Map(linkFormItemDTO, true);
        List<UserEntity> userList = userModel.findEntitys(params);
        if (userList == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.USER_NOT_EXIST);
        }
        Map<String, UserEntity> userMap = new HashMap<>(userList.size());
        userList.forEach((item) -> userMap.put(item.getUserId(), item));
        // 获取部门容器
        params.remove(ParameterConstant.COLUMNS);
        List<DepartmentEntity> departmentList = departmentModel.findEntitys(params);
        if (departmentList == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.DEPT_NOT_EXIST);
        }
        Map<String, DepartmentEntity> departmentMap = new HashMap<>(departmentList.size());
        departmentList.forEach((departmentItem) -> departmentMap.put(departmentItem.getId().toString(), departmentItem));

        ParseSingleRowDataDTO parseSingleRowDataDTO = new ParseSingleRowDataDTO();
        BeanUtil.copyProperties(linkFormItemDTO, parseSingleRowDataDTO);
        parseSingleRowDataDTO.setDepartmentMap(departmentMap);
        parseSingleRowDataDTO.setUserMap(userMap);
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(explainList.size());
        explainList.forEach(item -> {
            explainMap.put(item.getAttr(), item);
//            if ( Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.PAYMENT.getCode())) {
//                if ( Objects.equals(linkBusinessType, XbbRefTypeEnum.PAYMENT.getCode()) && Objects.equals(item.getAttr(),PaymentEnum.PAYMENT_NO.getAttr()) ){
//                    item.setParentAttr(ContractEnum.ADD_PAYMENT.getAttr());
//                } else if ( Objects.equals(linkBusinessType, XbbRefTypeEnum.WRITE_OFF_PREPAYMENT.getCode()) && Objects.equals(item.getAttr(),PaymentSheetEnum.SHEET_NO.getAttr())) {
//                    item.setParentAttr(ContractEnum.ADD_WRITE_OFF_PREPAYMENT.getAttr());
//                } else  if ( Objects.equals(linkBusinessType, XbbRefTypeEnum.PAYMENT_SHEET.getCode()) && Objects.equals(item.getAttr(),PaymentSheetEnum.SHEET_NO.getAttr())) {
//                    item.setParentAttr(ContractEnum.ADD_PAYMENT_SHEET.getAttr());
//                }
//            } else if ( Objects.equals(businessType, XbbRefTypeEnum.PAY_PLAN.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.PURCHASE.getCode())) {
//                if ( Objects.equals(linkBusinessType, XbbRefTypeEnum.PAY_PLAN.getCode()) ){
//                    item.setParentAttr(PurchaseEnum.ADD_PAYPLAN.getAttr());
//                } else if ( Objects.equals(linkBusinessType, XbbRefTypeEnum.WRITE_OFF_PREPAY.getCode()) ) {
//                    item.setParentAttr(PurchaseEnum.ADD_WRITE_OFF_PREPAY.getAttr());
//                } else  if ( Objects.equals(linkBusinessType, XbbRefTypeEnum.PAY_SHEET.getCode()) ) {
//                    item.setParentAttr(PurchaseEnum.ADD_PAY_SHEET.getAttr());
//                }
//            }
        });
        parseSingleRowDataDTO.setExplainMap(explainMap);
        //处理负责团队信息(一些业务负责团队的数据格式转化，以及对团队成员改造上线之前一些业务表单模板团队老数据回显)
        if (!Objects.equals(linkFormItemDTO.getDistributorMark(), DistributorMarkEnum.DISTRIBUTOR.getCode())) {
            handleTeam(corpid, formDataList, linkBusinessType, taskId, explainMap, dataObject, businessType, addTime);
        }
	    //处理回款单下的子回款单
        handlerLinkSheet(corpid, formDataList, paymentSheetFlag,paySheetFlag, dataId, userMap);
        for (PaasFormDataEntityExt item : formDataList) {
            JSONObject jsonObject = item.getData();
            //加入富文本数据
            richTextService.addRichTextByDataId(item.getId(), item.getCorpid(), item.getFormId(), linkFormItemDTO.getLinkBusinessType(), linkFormItemDTO.getSaasMark(), DelEnum.NORMAL.getDel(), jsonObject);
            Long departmentId = jsonObject.getLong(FieldTypeEnum.DEPARTMENTID.getAlias());
            jsonObject.put(FieldTypeEnum.DEPARTMENTID.getAlias(), Objects.nonNull(departmentId) ? departmentId : item.getDepartmentId());
            parseSingleRowDataDTO.setDataJsonObject(jsonObject);
            ParseSingleRowDataVO parseSingleRowDataVO;
            try {
                parseSingleRowDataVO = formDataLinkAddUpdateGetAnalysisDataHelp.parseSingleRowData(parseSingleRowDataDTO);
                LinkResultDataVO linkResultDataVO = parseSingleRowDataVO.getLinkResultDataVO();
                JSONObject result = parseSingleRowDataVO.getResult();
                // 获取关联数据的信息
                if (linkResultDataVO != null && !linkResultDataVO.getLinkData().isEmpty() && !linkResultDataVO.getLinkDataSet().isEmpty()) {
                    FormDataUpdateGetDTO formDataUpdateGetDTO = new FormDataUpdateGetDTO();
                    BeanUtil.copyProperties(linkFormItemDTO, formDataUpdateGetDTO);
                    linkResultDataVO.setData(result);
                    linkResultDataVO.setExplainMap(explainMap);
                    linkResultDataVO.setUserMap(userMap);
                    linkResultDataVO.setDepartmentMap(departmentMap);
                    linkResultDataVO.setExplainList(explainList);
                    result = formDataLinkDataUpdateGetService.formDataLinkDataGet(formDataUpdateGetDTO, linkResultDataVO);
                }
                SaasAnalysisDataDTO saasAnalysisDataDTO = new SaasAnalysisDataDTO();
                BeanUtil.copyProperties(linkFormItemDTO, saasAnalysisDataDTO);
                saasAnalysisDataDTO.setDataId(item.getId());
                saasAnalysisDataDTO.setBusinessType(linkBusinessType);
                // saas特殊格式转换
                saasAnalysisDataDTO.setExplainMap(explainMap);
                saasUpdateHelp.formatData(saasAnalysisDataDTO, result);
                item.setData(result);
                // 兼容一下dataId或id为空的情况
                if (Objects.isNull(item.getId())) {
                    item.setId(item.getDataId());
                } else if (Objects.isNull(item.getDataId())) {
                    item.setDataId(item.getId());
                }
            } catch (XbbException e) {
                LOG.error("paasFormExplainServiceImpl获取关联新建的解释和数据出错", e);
            }
        }

        linkFormItemVO.setFormDataList(formDataList);
        linkFormItemVO.setExplainList(explainList);
        JSONObject linkFormMessage = new JSONObject();
        linkFormMessage.put("appId", appId);
        linkFormMessage.put("menuId", menuId);
        linkFormMessage.put("formId", formId);
        linkFormMessage.put("formName", formName);
        linkFormItemVO.setLinkFormMessage(linkFormMessage);
        linkFormItemVO.setShowColumnList(showColumnList);
        return linkFormItemVO;
    }

    /**
     * 处理资金负责团队信息，这边主要是
     *
     * @param corpid 公司id
     * @param formDataList
     * @param linkBusinessType 业务类型
     * @param taskId 是否是审批
     * @param explainMap 表单解释
     * @param dataObject 审批里面的完整数据
     * @param businessType 主业务类型
     * @param addTime 创建时间
     */
    private void handleTeam(String corpid, List<PaasFormDataEntityExt> formDataList, Integer linkBusinessType,
                            Long taskId, Map<String, FieldAttrEntity> explainMap, JSONObject dataObject,
                            Integer businessType, Long addTime) throws XbbException {
        //下面代表是不是审批标识
        boolean approveTag = taskId != null && !Objects.equals(taskId, 0L);
        Map<Long, List<String>> mainUserIdMap = new HashMap<>();
        Map<Long, List<String>> coUserIdMap = new HashMap<>();
        Set<String> userIdList = new HashSet<>();
        Integer parentBusinessType = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
        if (!approveTag) {
            //只有是编辑才需要去数据库查询一波数据
            if (CollectionsUtil.isNotEmpty(formDataList)) {
                List<Long> formDataIdList = new ArrayList<>();
                formDataList.forEach(paasFormDataEntityExt -> {
                    formDataIdList.add(paasFormDataEntityExt.getDataId());
                });
                businessUserTeamHelp.getUserIdMapSetShow(userIdList, formDataIdList, corpid, linkBusinessType, false, mainUserIdMap,
                        coUserIdMap, BasicConstant.ZERO);
                for (PaasFormDataEntityExt paasFormDataEntityExt : formDataList) {
                    Long dataId = Objects.isNull(paasFormDataEntityExt.getId()) ? paasFormDataEntityExt.getDataId() : paasFormDataEntityExt.getId();
                    List<String> ownerIdList = mainUserIdMap.get(dataId);
                    List<String> coUserIdList = coUserIdMap.get(dataId);
                    JSONObject data = paasFormDataEntityExt.getData();
                    if (explainMap.containsKey(FieldTypeEnum.OWNERID.getAlias())) {
                        data.put(FieldTypeEnum.OWNERID.getAlias(), ownerIdList);
                    }
                    if (explainMap.containsKey(FieldTypeEnum.COUSERID.getAlias())) {
                        data.put(FieldTypeEnum.COUSERID.getAlias(), coUserIdList);
                    }
                }
            }
        }else {
            //需要把负责人、协同人的List<JSONObject>对象变成List<String>
            for (PaasFormDataEntityExt paasFormDataEntityExt : formDataList) {
                JSONObject data = paasFormDataEntityExt.getData();
                JSONArray ownerJsonArray = data.getJSONArray(FieldTypeEnum.OWNERID.getAlias());
                JSONArray coUserJsonArray = data.getJSONArray(FieldTypeEnum.COUSERID.getAlias());
                //目前只能通过判断负责人和协同人都为空的时候，判断为团队成员上线之前的老数据
                if ((Objects.isNull(ownerJsonArray) || ownerJsonArray.size() == BasicConstant.ZERO) &&
                        (Objects.isNull(coUserJsonArray) || coUserJsonArray.size() == BasicConstant.ZERO)) {
                    if (Objects.equals(XbbRefTypeEnum.CONTACT.getCode(), linkBusinessType) && Objects.nonNull(addTime) && addTime > TeamMembersConstant.OLD_TIME_DATA) {
                        //如果是5.25号之后的客户、联系人联合审批数据，如果负责人和协同人为空的话，不走拿客户的团队逻辑
                        return;
                    }
                    XbbRefTypeEnum  xbbRefTypeEnum = XbbRefTypeEnum.getByCode(linkBusinessType);
                    Object customerOrSupplierObj = null;
                    boolean contractOrSupplierContractTag = true;
                    switch (xbbRefTypeEnum) {
                        case PAYMENT:
                            parentBusinessType = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
                            customerOrSupplierObj = Long.valueOf(data.getString(PaymentEnum.CUSTOMER.getAttr()));
                            break;
                        case PAYMENT_SHEET:
                            parentBusinessType = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
                            customerOrSupplierObj = Long.valueOf(data.getString(PaymentSheetEnum.CUSTOMER_ID.getAttr()));
                            break;
                        case WRITE_OFF_PREPAYMENT:
                            parentBusinessType = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
                            customerOrSupplierObj = Long.valueOf(data.getString(PaymentSheetEnum.CUSTOMER_ID.getAttr()));
                            contractOrSupplierContractTag = false;
                            break;
                        case PAY_PLAN:
                            parentBusinessType = XbbRefTypeEnum.SUPPLIER.getCode();
                            customerOrSupplierObj = Long.valueOf(data.getString(PayPlanEnum.LINK_SUPPLIER.getAttr()));
                            break;
                        case PAY_SHEET:
                            parentBusinessType = XbbRefTypeEnum.SUPPLIER.getCode();
                            customerOrSupplierObj = Long.valueOf(data.getString(PaySheetEnum.LINK_SUPPLIER.getAttr()));
                            break;
                        case WRITE_OFF_PREPAY:
                            parentBusinessType = XbbRefTypeEnum.SUPPLIER.getCode();
                            customerOrSupplierObj = Long.valueOf(data.getString(PaySheetEnum.LINK_SUPPLIER.getAttr()));
                            contractOrSupplierContractTag = false;
                            break;
                    }
                    //兼容一下老数据，工作流transfer表有的团队数据不是数组存储的情况
                    Object ownerObject = dataObject.get(FieldTypeEnum.OWNERID.getAlias());
                    Object coUserObject = dataObject.get(FieldTypeEnum.COUSERID.getAlias());
                    JSONArray mainOwnerJsonArray;
                    JSONArray mainCouserJsonArray;
                    if(ownerObject instanceof JSONArray){
                        mainOwnerJsonArray = (JSONArray) JSONArray.parse(ownerObject.toString());
                    }else{
                        mainOwnerJsonArray = new JSONArray();
                        mainOwnerJsonArray.add(ownerObject);
                    }
                    if(coUserObject instanceof JSONArray){
                        mainCouserJsonArray = (JSONArray) JSONArray.parse(coUserObject.toString());
                    }else{
                        mainCouserJsonArray = new JSONArray();
                        mainCouserJsonArray.add(coUserObject);
                    }
                    if (Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode()) ||
                    Objects.equals(businessType, XbbRefTypeEnum.PURCHASE.getCode())) {
                        if (!contractOrSupplierContractTag) {
                            //说明需要获取客户或者供应商的负责团队
                            businessUserTeamHelp.getUserIdMapSetShow(userIdList, Arrays.asList((long)customerOrSupplierObj), corpid, parentBusinessType, false, mainUserIdMap,
                                    coUserIdMap, BasicConstant.ZERO);
                            List<String> mainUserList = mainUserIdMap.get((long)customerOrSupplierObj);
                            List<String> coUserList =  coUserIdMap.get((long)customerOrSupplierObj);
                            data.put(FieldTypeEnum.OWNERID.getAlias(), mainUserList);
                            data.put(FieldTypeEnum.COUSERID.getAlias(), coUserList);
                        }else {
                            //直接拿合同/采购合同的负责人、协同人
                            data.put(FieldTypeEnum.OWNERID.getAlias(), mainOwnerJsonArray);
                            data.put(FieldTypeEnum.COUSERID.getAlias(), mainCouserJsonArray);
                        }
                    }else {
                        //这里包含联系人和供应商联系人
                        data.put(FieldTypeEnum.OWNERID.getAlias(), mainOwnerJsonArray);
                        data.put(FieldTypeEnum.COUSERID.getAlias(), mainCouserJsonArray);
                    }
                }else {
                    if (Objects.nonNull(ownerJsonArray) && ownerJsonArray.size() > BasicConstant.ZERO) {
                        List<String> ownerIdList = new ArrayList<>();
                        for (int i = 0; i < ownerJsonArray.size(); i++) {
                            try {
                                JSONObject ownerJson = ownerJsonArray.getJSONObject(i);
                                String ownerId = ownerJson.getString(BasicConstant.ID);
                                ownerIdList.add(ownerId);
                            } catch (Exception e) {
                                LOG.error("PaasFormExplainServiceImpl-handleTeam-" + Objects.toString(ownerJsonArray));
                                LOG.error(e.getMessage());
                            }
                        }
                        data.put(FieldTypeEnum.OWNERID.getAlias(), ownerIdList);
                    }
                    if (Objects.nonNull(coUserJsonArray) && coUserJsonArray.size() > BasicConstant.ZERO) {
                        List<String> coUserIdList = new ArrayList<>();
                        for (int i = 0; i < coUserJsonArray.size(); i++) {
                            try {
                                JSONObject coUserJson = coUserJsonArray.getJSONObject(i);
                                String coUserId = coUserJson.getString(BasicConstant.ID);
                                coUserIdList.add(coUserId);
                            } catch (Exception e) {
                                LOG.error("PaasFormExplainServiceImpl-handleTeam-" + Objects.toString(coUserJsonArray));
                                LOG.error(e.getMessage());
                            }
                        }
                        data.put(FieldTypeEnum.COUSERID.getAlias(), coUserIdList);
                    }
                }
            }
        }

    }

    /**
     *
     *
     * @param data data里面的数据
     * @param dataId 数据id
     * @param mainUserIdMap dataId跟负责人userId的一个map
     * @param coUserIdMap dataId跟协同人userId的一个map
     * @param explainMap 表单解释map
     */
    private void packageFundTeam(JSONObject data, Long dataId, Map<Long, List<String>> mainUserIdMap, Map<Long,
            List<String>> coUserIdMap, Map<String, FieldAttrEntity> explainMap) {
        List<String> ownerIdList = mainUserIdMap.get(dataId);
        List<String> coUserIdList = coUserIdMap.get(dataId);

    }

    /**
     * 处理应收款新增的表单解释
     *
     * @param explainList
     */
    private void handPaymentAddExplain(List<FieldAttrEntity> explainList) {
        explainList.forEach(fieldAttrEntity -> {
            if (Objects.equals(fieldAttrEntity.getAttr(), PaymentEnum.SOURCE.getAttr())) {
                fieldAttrEntity.setVisible(BasicConstant.ZERO);
            }
        });
    }

    /**
     * 处理审批详情页需要移除的信息
     *
     * @param linkArray 合同下的回款单或者回款计划/采购合同下的付款单或付款计划
     * @param xbbRefTypeEnum 主业务类型，比如合同或者采购合同业务类型
     * @param linkXbbRefTypeEnum 子业务类型，比如回款单、回款计划、付款单、付款计划
     */
    @Override
    public void handProcessShouldRemoveValue(String corpid, XbbRefTypeEnum xbbRefTypeEnum, XbbRefTypeEnum linkXbbRefTypeEnum, JSONArray linkArray) throws XbbException {
        fundHelp.handProcessShouldRemoveValue(corpid, xbbRefTypeEnum, linkXbbRefTypeEnum, linkArray);
    }



    /**
     * 有木有编辑删除的权限
     *
     * @param formDataList
     * @param linkBusinessType
     * @param linkFormItemDTO
     * @return
     */
    @Override
    public List<PaasFormDataEntityExt> checkDataHavaEditAndDelPermission(List<PaasFormDataEntityExt> formDataList, Integer linkBusinessType, LinkFormItemDTO linkFormItemDTO, boolean isProcess) throws XbbException {
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(linkBusinessType);
        Set<String> permSet = linkFormItemDTO.getLoginUser().getPermSet();
        boolean editRolePermission;
        boolean delRolePermission;
        Integer operationFlag = 1;
        switch (xbbRefTypeEnum) {
            case CONTACT:
                editRolePermission = permSet.contains(ProPermissionAliasEnum.CONTACT_UPDATE.getAlias());
                delRolePermission = permSet.contains(ProPermissionAliasEnum.CONTACT_DELETE.getAlias());
                for (PaasFormDataEntityExt paasFormDataEntityExt : formDataList) {
                    if (isProcess) {
                        Long dataId = paasFormDataEntityExt.getDataId();
                        if (Objects.isNull(dataId)) {
                            paasFormDataEntityExt.setEditPermission(editRolePermission);
                            paasFormDataEntityExt.setDelPermission(delRolePermission);
                        }else {
                            paasFormDataEntityExt.setEditPermission(false);
                            paasFormDataEntityExt.setDelPermission(false);
                        }
                    }else {
                        paasFormDataEntityExt.setEditPermission(editRolePermission);
                        paasFormDataEntityExt.setDelPermission(delRolePermission);
                    }
                    JSONObject data = paasFormDataEntityExt.getData();
                    if (StringUtil.isEmpty(paasFormDataEntityExt.getSerialNo()) && Objects.nonNull(paasFormDataEntityExt.getData().getString(FieldTypeEnum.SERIALNO.getAlias()))) {
                        paasFormDataEntityExt.setSerialNo(paasFormDataEntityExt.getData().getString(FieldTypeEnum.SERIALNO.getAlias()));
                    }
                    showFormatHelp.formatBirthday4Show(data, ContactEnum.BIRTHDAY.getAttr(), ContactEnum.BIRTHDAY_FLAG.getAttr());
                }
                break;
            case SUPPLIER_CONTACT:
                editRolePermission = permSet.contains(ProPermissionAliasEnum.SUPPLIER_CONTACT_UPDATE.getAlias());
                delRolePermission = permSet.contains(ProPermissionAliasEnum.SUPPLIER_CONTACT_DELETE.getAlias());
                for (PaasFormDataEntityExt paasFormDataEntityExt : formDataList) {
                    Long dataId = paasFormDataEntityExt.getDataId();
                    if (Objects.nonNull(dataId) && isProcess) {
                        paasFormDataEntityExt.setEditPermission(false);
                        paasFormDataEntityExt.setDelPermission(false);
                    }else {
                        paasFormDataEntityExt.setEditPermission(editRolePermission);
                        paasFormDataEntityExt.setDelPermission(delRolePermission);
                    }
                }
                break;
            case PAY_PLAN:
                editRolePermission = permSet.contains(ProPermissionAliasEnum.PAY_PLAN_UPDATE.getAlias());
                delRolePermission = permSet.contains(ProPermissionAliasEnum.PAY_PLAN_DELETE.getAlias());
                for (PaasFormDataEntityExt paasFormDataEntityExt : formDataList) {
                    Long dataId = paasFormDataEntityExt.getDataId();
                    if ( isProcess ) {
                        if (StringUtil.isEmpty(paasFormDataEntityExt.getSerialNo())) {
                            paasFormDataEntityExt.setSerialNo(paasFormDataEntityExt.getData().getString(FieldTypeEnum.SERIALNO.getAlias()));
                        }
                        if ( Objects.isNull(dataId) && Objects.isNull(paasFormDataEntityExt.getOperationFlag())) {
                            operationFlag = 0;
                        } else if (Objects.nonNull(paasFormDataEntityExt.getOperationFlag())) {
                            operationFlag = paasFormDataEntityExt.getOperationFlag();
                        }
                    }
                    paasFormDataEntityExt.setOperationFlag(operationFlag);
                    if (!Objects.equals(paasFormDataEntityExt.getData().getString(PayPlanEnum.STATUS.getAttr()), PayPlanStatusEnum.UN_RECEIVABLES.getCode())) {
                        paasFormDataEntityExt.setEditPermission(false);
                        paasFormDataEntityExt.setDelPermission(false);
                    } else if (isProcess && Objects.nonNull(dataId)) {
                        paasFormDataEntityExt.setEditPermission(false);
                        paasFormDataEntityExt.setDelPermission(false);
                    }else {
                        paasFormDataEntityExt.setEditPermission(editRolePermission);
                        paasFormDataEntityExt.setDelPermission(delRolePermission);
                    }
                }
                break;
            case PAYMENT:
                editRolePermission = permSet.contains(ProPermissionAliasEnum.PAYMENT_UPDATE.getAlias());
                delRolePermission = permSet.contains(ProPermissionAliasEnum.PAYMENT_DELETE.getAlias());
                for (PaasFormDataEntityExt paasFormDataEntityExt : formDataList) {
                    Long modelType = paasFormDataEntityExt.getSysLong10();
                    JSONObject data = paasFormDataEntityExt.getData();
                    Long dataId = paasFormDataEntityExt.getDataId();
                    if ( isProcess ) {
                        if (StringUtil.isEmpty(paasFormDataEntityExt.getSerialNo())) {
                            paasFormDataEntityExt.setSerialNo(data.getString(FieldTypeEnum.SERIALNO.getAlias()));
                        }
                        if ( Objects.isNull(dataId) && Objects.isNull(paasFormDataEntityExt.getOperationFlag())) {
                            operationFlag = 0;
                        } else if (Objects.nonNull(paasFormDataEntityExt.getOperationFlag())) {
                            operationFlag = paasFormDataEntityExt.getOperationFlag();
                        }
                    }
                    paasFormDataEntityExt.setOperationFlag(operationFlag);
                    if (isProcess && Objects.nonNull(dataId)) {
                        paasFormDataEntityExt.setEditPermission(false);
                        paasFormDataEntityExt.setDelPermission(false);
                    } else {
                        //现在只有在第一种模式下生成的未已收的应收款才能编辑; 现在只有在第一种模式下生成的未收款的应收款才能删除;
                        if (PaymentStatusEnum.getPaymentUnEditStatus().contains(paasFormDataEntityExt.getData().getString(PaymentEnum.STATUS.getAttr()))
                                || (!Objects.equals(modelType, ModelTypeEnum.PLAN.getCode()) && Objects.nonNull(modelType))) {
                            paasFormDataEntityExt.setEditPermission(false);
                        } else {
                            paasFormDataEntityExt.setEditPermission(editRolePermission);
                        }
                        if (!Objects.equals(paasFormDataEntityExt.getData().getString(PaymentEnum.STATUS.getAttr()), PaymentStatusEnum.UN_RECEIVABLES.getCode())
                                || (!Objects.equals(modelType, ModelTypeEnum.PLAN.getCode()) && Objects.nonNull(modelType))) {
                            paasFormDataEntityExt.setDelPermission(false);
                        } else {
                            paasFormDataEntityExt.setDelPermission(delRolePermission);
                        }
                    }
                }
                break;
            case PAYMENT_SHEET:
            case WRITE_OFF_PREPAYMENT:
                editRolePermission = permSet.contains(ProPermissionAliasEnum.PAYMENT_SHEET_UPDATE.getAlias());
                delRolePermission = permSet.contains(ProPermissionAliasEnum.PAYMENT_SHEET_DELETE.getAlias());
                for ( PaasFormDataEntityExt paasFormDataEntityExt : formDataList ) {
                    if ( isProcess ) {
                        if (StringUtil.isEmpty(paasFormDataEntityExt.getSerialNo())) {
                            paasFormDataEntityExt.setSerialNo(paasFormDataEntityExt.getData().getString(FieldTypeEnum.SERIALNO.getAlias()));
                        }
                        Long dataId = paasFormDataEntityExt.getDataId();
                        if ( Objects.isNull(dataId) && Objects.isNull(paasFormDataEntityExt.getOperationFlag())) {
                            operationFlag = 0;
                        } else if (Objects.nonNull(paasFormDataEntityExt.getOperationFlag())) {
                            operationFlag = paasFormDataEntityExt.getOperationFlag();
                        }
                        if (Objects.isNull(dataId)) {
                            paasFormDataEntityExt.setEditPermission(editRolePermission);
                            paasFormDataEntityExt.setDelPermission(delRolePermission);
                        }else {
                            paasFormDataEntityExt.setEditPermission(false);
                            paasFormDataEntityExt.setDelPermission(false);
                        }
                    }else {
                        paasFormDataEntityExt.setEditPermission(false);
                        paasFormDataEntityExt.setDelPermission(false);
                    }
                    paasFormDataEntityExt.setOperationFlag(operationFlag);
                }
                break;
            case PAY_SHEET:
            case WRITE_OFF_PREPAY:
                editRolePermission = permSet.contains(ProPermissionAliasEnum.PAY_SHEET_UPDATE.getAlias());
                delRolePermission = permSet.contains(ProPermissionAliasEnum.PAY_SHEET_DELETE.getAlias());
                for (PaasFormDataEntityExt paasFormDataEntityExt : formDataList) {
                    if ( isProcess ) {
                        if (StringUtil.isEmpty(paasFormDataEntityExt.getSerialNo())) {
                            paasFormDataEntityExt.setSerialNo(paasFormDataEntityExt.getData().getString(FieldTypeEnum.SERIALNO.getAlias()));
                        }
                        Long dataId = paasFormDataEntityExt.getDataId();
                        if ( Objects.isNull(dataId) && Objects.isNull(paasFormDataEntityExt.getOperationFlag())) {
                            operationFlag = 0;
                        } else if (Objects.nonNull(paasFormDataEntityExt.getOperationFlag())) {
                            operationFlag = paasFormDataEntityExt.getOperationFlag();
                        }
                        if (Objects.isNull(dataId)) {
                            paasFormDataEntityExt.setEditPermission(editRolePermission);
                            paasFormDataEntityExt.setDelPermission(delRolePermission);
                        }else {
                            paasFormDataEntityExt.setEditPermission(false);
                            paasFormDataEntityExt.setDelPermission(false);
                        }
                    }else {
                        paasFormDataEntityExt.setEditPermission(false);
                        paasFormDataEntityExt.setDelPermission(false);
                    }
                    paasFormDataEntityExt.setOperationFlag(operationFlag);
                }
                break;
            default:
                break;
        }
        return formDataList;
    }

    @Override
    public Boolean checkRequiredByAttr(List<FieldAttrEntity> explainList, String attr) throws XbbException {
        if (explainList == null || attr == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002);
        }
        // 默认不必填
        boolean result = false;
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            if (Objects.equals(fieldAttrEntity.getAttr(), attr)) {
                Integer required = fieldAttrEntity.getRequired();
                result = Objects.equals(required, 1);
                break;
            }
        }
        return result;
    }

    @Override
    public Boolean checkRequiredBySaasAttr(List<FieldAttrEntity> explainList, String saasAttr) throws XbbException {
        if (explainList == null || saasAttr == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002);
        }
        // 默认不必填
        boolean result = false;
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            if (Objects.equals(fieldAttrEntity.getSaasAttr(), saasAttr)) {
                Integer required = fieldAttrEntity.getRequired();
                result = Objects.equals(required, 1);
                break;
            }
        }
        return result;
    }

    @Override
    public Boolean checkVisibleByAttr(List<FieldAttrEntity> explainList, String attr) throws XbbException {
        if (explainList == null || attr == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002);
        }
        // 默认不启用
        boolean result = false;
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            if (Objects.equals(fieldAttrEntity.getAttr(), attr)) {
                Integer visible = fieldAttrEntity.getVisible();
                result = Objects.equals(visible, 1);
                break;
            }
        }
        return result;
    }

    @Override
    public Boolean checkProductCostVisibleByAttr(String corpid) throws XbbException {
        // 获取产品的解释
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(), corpid);
        List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);

        return checkVisibleByAttr(explainList, ProductEnum.COST.getAttr());
    }

    @Override
    public Map<String, FieldAttrEntity> getFieldAttrMapByBusinessType(Integer businessType, String corpid) throws XbbException {
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByBusinessType(businessType, corpid);
        if (paasFormExplainEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028);
        }
        List<FieldAttrEntity> fieldAttrEntities = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        Map<String, FieldAttrEntity> fieldAttrEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        fieldAttrEntities.forEach(item -> fieldAttrEntityMap.put(item.getAttr(), item));
        return fieldAttrEntityMap;
    }

    @Override
    public Map<String, FieldAttrEntity> getExpalinMap(List<FieldAttrEntity> explainList, Integer businessType, String corpid, Long formId) throws XbbException {
        Map<String, FieldAttrEntity> expalinMap = new HashMap<>(explainList.size());
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode()) && Objects.equals(fieldAttrEntity.getSaasAttr(), WorkOrderEnum.STAGE.getSaasAttr())) {
                if (!Objects.equals(formId, 0L)) {
                    //工单阶段
                    WorkOrderTemplateEntity workOrderTemplateEntity = workOrderTemplateService.getByFormId(formId, corpid);
                    List<ItemPoJo> itemPoJoList = workOrderStageService.getStageNameItemList(workOrderTemplateEntity.getId(), corpid);
                    fieldAttrEntity.setItems(itemPoJoList);
                }
            }
            if (Objects.equals(FieldTypeEnum.SELECT_PRODUCT.getType(),fieldAttrEntity.getFieldType())){
                SubFormPoJo subForm = fieldAttrEntity.getSubForm();
                if (subForm != null && subForm.getItems() != null) {
                    List<? extends FieldAttrEntity> subExplainList = subForm.getItems();
                    Iterator<? extends FieldAttrEntity> iterator = subExplainList.iterator();
                    while (iterator.hasNext()){
                        FieldAttrEntity subFieldAttrEntity = iterator.next();
                        if (Objects.equals(subFieldAttrEntity.getAttr(),SelectProductEnum.PRODUCT.getAttr())){
                            subFieldAttrEntity.setFieldType(FieldTypeEnum.TEXT.getType());
                            break;
                        }
                    }
                }
            }
            expalinMap.put(fieldAttrEntity.getAttr(),fieldAttrEntity);
        }
        return expalinMap;
    }

    @Override
    public List<FieldAttrEntity> handleExplainList(List<FieldAttrEntity> explainList, Integer businessType, String corpid, Long formId) throws XbbException {
        return proFormHelp.handleExplainList(explainList, businessType, corpid, formId);
    }

    @Override
    public FormExplainDeleteVO delete(FormExplainDeleteDTO formExplainDeleteDTO) throws XbbException {
        FormExplainDeleteVO formExplainDeleteVO = new FormExplainDeleteVO();
        try {
            String corpid = formExplainDeleteDTO.getCorpid();
            Map<String, Object> param = BeanUtil.convertBean2Map(formExplainDeleteDTO, true);

            List<PaasFormExplainEntity> formExplainList = paasFormExplainModel.list(param);
            if (Objects.isNull(formExplainList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            if (formExplainList.size() == 1) {
                PaasFormExplainEntity paasFormExplainEntity = formExplainList.get(0);
                paasFormExplainModel.delete(paasFormExplainEntity.getId(), corpid);
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormExplain.delete 出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formExplainDeleteVO;
    }

    @Override
    public LinkKeyExplainListVO linkKeyList(LinkKeyExplainListDTO linkKeyExplainListDTO) throws XbbException {
        LinkKeyExplainListVO linkKeyExplainListVO = new LinkKeyExplainListVO();
        try {
            String corpid = linkKeyExplainListDTO.getCorpid();
            Integer businessType = linkKeyExplainListDTO.getBusinessType();
            PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), businessType)) {
                // 工单逻辑
                WorkOrderExplainEntityExt workOrderExplainEntityExt = workOrderExplainModel.getByFormId(linkKeyExplainListDTO.getFormId(), corpid);
                if (workOrderExplainEntityExt == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                }
                BeanUtil.copyProperties(workOrderExplainEntityExt, paasFormExplainEntity);
            } else {
                paasFormExplainEntity = paasFormExplainModel.getByFormId(linkKeyExplainListDTO.getFormId(), corpid);
            }
            if (paasFormExplainEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            List<FieldAttrEntity> explainJsonArray = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            Iterator<FieldAttrEntity> iterator = explainJsonArray.iterator();
            while (iterator.hasNext()) {
                FieldAttrEntity fieldAttrEntity = iterator.next();
                Integer showType = fieldAttrEntity.getShowType();
                Boolean invisible = Objects.nonNull(fieldAttrEntity.getShowType()) && (ShowTypeEnum.LIST.getCode() == showType || ShowTypeEnum.DETAIL.getCode() == showType
                        || ShowTypeEnum.LIST_DETAIL.getCode() == showType || ShowTypeEnum.NONE.getCode() == showType);
                if (invisible || Objects.equals(fieldAttrEntity.getIsOpen(), 2) || Objects.isNull(LinkKeyExplainEnum.getFieldTypeEnum(fieldAttrEntity.getFieldType()))) {
                    iterator.remove();
                }
            }
            linkKeyExplainListVO.setFormExplainList(explainJsonArray);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormExplain.linkKeyList 出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return linkKeyExplainListVO;
    }

    @Override
    public DynamicManagerVO dynamicManager(DynamicManagerDTO dynamicManagerDTO) throws XbbException {
        DynamicManagerVO dynamicManagerVO = new DynamicManagerVO();
        try {
            String corpid = dynamicManagerDTO.getCorpid();
            Integer businessType = dynamicManagerDTO.getBusinessType();
            PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
            List<Integer> dynamicFieldTypeList;
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), businessType)) {
                // 工单逻辑
                WorkOrderExplainEntityExt workOrderExplainEntityExt = workOrderExplainModel.getByFormId(dynamicManagerDTO.getFormId(), corpid);
                if (Objects.isNull(workOrderExplainEntityExt)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                BeanUtil.copyProperties(workOrderExplainEntityExt, paasFormExplainEntity);
                // 动态负责人：提交人、协同人、成员单选、成员多选(去掉负责人)
                dynamicFieldTypeList = Arrays.asList(FieldTypeEnum.CREATORID.getType(), FieldTypeEnum.COUSERID.getType(), FieldTypeEnum.USER.getType(), FieldTypeEnum.USER_GROUP.getType());
            } else {
                paasFormExplainEntity = paasFormExplainModel.getByFormId(dynamicManagerDTO.getFormId(), corpid);
                if (Objects.equals(dynamicManagerDTO.getStageWorkExecutorSet(), 1)) {
                    dynamicFieldTypeList = Arrays.asList(FieldTypeEnum.OWNERID.getType(), FieldTypeEnum.COUSERID.getType(), FieldTypeEnum.USER.getType(), FieldTypeEnum.USER_GROUP.getType());
                } else {
                    // 动态负责人：提交人、负责人、协同人、成员单选、
                    dynamicFieldTypeList = Arrays.asList(FieldTypeEnum.CREATORID.getType(), FieldTypeEnum.OWNERID.getType(), FieldTypeEnum.COUSERID.getType(), FieldTypeEnum.USER.getType(), FieldTypeEnum.USER_GROUP.getType());
                }
            }
            if (paasFormExplainEntity != null) {

                List<ReturnExplainPojo> explainPojoList = new ArrayList<>();
                List<FieldAttrEntity> explainList = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                // 动态负责人：提交人、负责人、协同人、成员单选、成员多选
                // List<Integer> dynamicFieldTypeList = Arrays.asList(FieldTypeEnum.CREATORID.getType(), FieldTypeEnum.OWNERID.getType(),
                //         FieldTypeEnum.COUSERID.getType(), FieldTypeEnum.USER.getType(), FieldTypeEnum.USER_GROUP.getType());

                for (FieldAttrEntity attrEntity : explainList) {

                    if (Objects.equals(BasicConstant.IS_USE, attrEntity.getVisible()) && dynamicFieldTypeList.contains(attrEntity.getFieldType())) {
                        ReturnExplainPojo pojo = new ReturnExplainPojo();
                        pojo.setAttr(attrEntity.getAttr());
                        pojo.setName(attrEntity.getAttrName());
                        if (Objects.equals(FieldTypeEnum.CREATORID.getType(), attrEntity.getFieldType())) {
                            pojo.setName(I18nMessageUtil.getMessage(I18nStringConstant.SUBMITTER));
                        }
                        explainPojoList.add(pojo);
                    }
                }

                dynamicManagerVO.setFormExplainList(explainPojoList);
            } else {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormExplain数据库搜索表单字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }

        return dynamicManagerVO;
    }

    @Override
    public ExplainMapLinkDataVO explainMapByLinkData(ExplainMapLinkDataDTO explainMapLinkDataDTO) throws XbbException {
        ExplainMapLinkDataVO explainMapLinkDataVO = new ExplainMapLinkDataVO();
        try {
            List<FieldAttrEntity> fieldAttrEntityList = explainMapLinkDataDTO.getExplainList();
            String corpid = explainMapLinkDataDTO.getCorpid();
            Map<Long, PaasFormExplainEntity> formExplainMap = paasFormHelp.getLinkFormExplain(fieldAttrEntityList, corpid);
            Map<Long, WorkOrderExplainEntity> workOrderExplainMap = paasFormHelp.getWorkOrderLinkFormExplain(fieldAttrEntityList, corpid);
            explainMapLinkDataVO.setFormExplainMap(formExplainMap);
            explainMapLinkDataVO.setWorkOrderExplainMap(workOrderExplainMap);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormExplain.explainMapByLinkData 出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return explainMapLinkDataVO;
    }

    /**
     * 获取付款单/回款单的回款账户/付款账户列表
     *
     * @param accountListDTO
     * @return
     * @throws XbbException
     */
    @Override
    public AccountListVO getAccountList(AccountListDTO accountListDTO) throws XbbException {
        AccountListVO accountListVO = new AccountListVO();
        Integer businessType = accountListDTO.getBusinessType();
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        String linkAttr = null;
        switch (xbbRefTypeEnum) {
            case PAYMENT_SHEET:
                linkAttr = PaymentSheetEnum.FUND_ACCOUNT.getAttr();
                break;
            case PAY_SHEET:
                linkAttr = PaySheetEnum.FUND_ACCOUNT.getAttr();
                break;
            default:
                throw new XbbException(BusinessTypeErrorCodeEnum.API_ERROR_361001);
        }
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByBusinessType(businessType,accountListDTO.getCorpid());
        if ( Objects.isNull(paasFormExplainEntity) ){
            throw new XbbException(TemplateErrorCodeEnum.API_ERROR_350002);
        }
        List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        FieldAttrEntity accountAttr = new FieldAttrEntity();
        for ( FieldAttrEntity fieldAttrEntity : explainList ) {
            if ( fieldAttrEntity.getAttr() != null && fieldAttrEntity.getAttr().equals(linkAttr) ) {
                accountAttr = fieldAttrEntity;
                List<ItemPoJo> itemPoJoList = proFormHelp.handleFundAccountItems(accountListDTO.getCorpid(), businessType);
                itemPoJoList.removeIf(e -> e.getShowType() == ShowTypeEnum.EXCLUDE_NEW.getCode());
                accountAttr.setItems(itemPoJoList);
                break;
            }
        }
        accountListVO.setFieldAttrEntity(accountAttr);
        return accountListVO;
    }


    @Override
    public ProductDataRelyVO productDataRely(ProductDataRelyDTO productDataRelyDTO) throws XbbException {
        String corpid = productDataRelyDTO.getCorpid();
        Integer businessType = productDataRelyDTO.getBusinessType();
        Long sourceFromId = productDataRelyDTO.getSourceFormId();
        String attr = productDataRelyDTO.getAttr();

        LinkProductRelyEnum linkProductRelyEnum;
        if (Objects.equals(XbbRefTypeEnum.PRODUCTION_ORDER.getCode(), businessType)) {
            if (ProductionOrderEnum.PRODUCT.getAttr().equals(attr)) {
                linkProductRelyEnum = LinkProductRelyEnum.PRODUCTION_ORDER_FINISH_PRODUCT_RELY_BOM;
            } else {
                linkProductRelyEnum = LinkProductRelyEnum.PRODUCTION_ORDER_MATERIEL_PRODUCT_RELY_BOM;
            }
        } else {
            linkProductRelyEnum = LinkProductRelyEnum.getByBuinessTypeAndSourceBusinessType(businessType, productDataRelyDTO.getSourceBusinessType());
        }

        if (Objects.isNull(linkProductRelyEnum)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, "获取联动关系失败");
        }
        // 添加所选数据字段
        FieldAttrEntity targetFieldAttrEntity = new FieldAttrEntity();
        targetFieldAttrEntity.setAttr(FieldTypeEnum.DATAID.getAlias());
        targetFieldAttrEntity.setAttrName("所选数据");
        targetFieldAttrEntity.setFieldType(FieldTypeEnum.DATAID.getType());
        // 获取联动表单
        Integer sourceBusinessType = linkProductRelyEnum.getSourceBusinessType();
        PaasFormExplainEntity sourceFormExplainEntity;
        Map<String, FieldAttrEntity> explainMap;
        if (Objects.equals(sourceBusinessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
            WorkOrderExplainEntityExt workOrderExplainEntityExt = workOrderExplainModel.getByFormId(sourceFromId, corpid);
            explainMap = ExplainUtil.getExplainMap(workOrderExplainEntityExt.getExplains());
        } else {
            sourceFormExplainEntity = paasFormExplainModel.getByFormId(sourceFromId, corpid);
            explainMap = ExplainUtil.getExplainMap(sourceFormExplainEntity.getExplains());
        }

        if (MapUtils.isEmpty(explainMap)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }

        // 联动表单
        RelyPoJo relyPoJo = new RelyPoJo();
        relyPoJo.setDisplayField(linkProductRelyEnum.getDisplayField());
        relyPoJo.setLinkField(linkProductRelyEnum.getLinkField());
        relyPoJo.setLinkFieldType(FieldTypeEnum.SELECT_PRODUCT.getType());
        relyPoJo.setTargetField(linkProductRelyEnum.getTargetField());
        relyPoJo.setTargetFieldType(BasicConstant.ZERO);
        relyPoJo.setSourceAppId(productDataRelyDTO.getSourceAppId());
        relyPoJo.setSourceBusinessType(sourceBusinessType);
        relyPoJo.setSourceMenuId(productDataRelyDTO.getSourceMenuId());
        relyPoJo.setSourceFormId(sourceFromId);
        relyPoJo.setSourceSaasMark(productDataRelyDTO.getSourceSaasMark());
//        relyPoJo.setSubRelyFieldList(new ArrayList<>());

        // 联动字段
        List<FieldAttrEntity> targetFieldList = new ArrayList<>();
        List<FieldAttrEntity> linkFieldList = new ArrayList<>();
        targetFieldList.add(targetFieldAttrEntity);
        linkFieldList.add(explainMap.get(linkProductRelyEnum.getLinkField()));

        ProductDataRelyVO productDataRelyVO = new ProductDataRelyVO();
        productDataRelyVO.setTargetFieldList(targetFieldList);
        productDataRelyVO.setLinkFieldList(linkFieldList);
        productDataRelyVO.setRely(relyPoJo);
        productDataRelyVO.setDefaultType(DefaultTypeEnum.PRODUCT_DATA_RELY.getAlias());
        return productDataRelyVO;
    }

    @Override
    public List<RelyPoJo> selectProductRely(String corpid, Long formId) {
        return linkProductRelyModel.selectProductRely(corpid, formId);
    }

    @Override
    public ExplainFilterConditionVO ruleFilterConditionList(ExplainFilterConditionDTO explainFilterConditionDTO) throws XbbException {
        ExplainFilterConditionVO explainFilterConditionVO = new ExplainFilterConditionVO();
        try {
            String corpid = explainFilterConditionDTO.getCorpid();
            PaasFormExplainEntity paasFormExplainEntity = proFormHelp.getExplainEntity(corpid, explainFilterConditionDTO.getFormId(), explainFilterConditionDTO.getBusinessType());

            List<String> list = TriggerConditionBusinessFieldEnum.getAttrsByCode(explainFilterConditionDTO.getBusinessType());

            Map<Integer, List<String>> fieldBlockMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            fieldBlockMap.put(XbbRefTypeEnum.PAYMENT_SHEET.getCode(), Arrays.asList(PaymentSheetEnum.PAY_METHOD.getAttr(), PaymentSheetEnum.FUND_ACCOUNT.getAttr()));
            fieldBlockMap.put(XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), Arrays.asList(SalesOpportunityEnum.WIN_COMPETITOR.getAttr()));
            List<FieldAndLogicPojo> conditionFieldList = new ArrayList<>();
            if(paasFormExplainEntity != null ) {
                Integer businessType = paasFormExplainEntity.getBusinessType();
                List<FieldAttrEntity> fieldList = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                Iterator<FieldAttrEntity> iterator = fieldList.iterator();
                while (iterator.hasNext()) {
                    // 过滤掉非自定义字段和子表单
                    FieldAttrEntity fieldAttrEntity = iterator.next();
                    Integer fieldType = fieldAttrEntity.getFieldType();
                    if (fieldBlockMap.containsKey(businessType)) {
                        List<String> fieldBlockList = fieldBlockMap.get(businessType);
                        if (fieldBlockList.contains(fieldAttrEntity.getAttr())) {
                            continue;
                        }
                    }
                    if (!ExplainUtil.isSubForm(fieldType)) {
                        // 过滤条件
                        FieldAndLogicPojo conditionField = getFilterConditionFieldAndLogic(fieldAttrEntity, list);
                        if (Objects.nonNull(conditionField)) {
                            conditionFieldList.add(conditionField);
                        }
                    }
                }
            }
            explainFilterConditionVO.setExplainList(conditionFieldList);
        } catch (Exception e) {
            LOG.error("paasFormExplainService.ruleFilterConditionList出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return explainFilterConditionVO;
    }

    @Override
    public ExplainFilterConditionVO optionalRangeConditionList(ExplainFilterConditionDTO explainFilterConditionDTO) throws XbbException {
        ExplainFilterConditionVO explainFilterConditionVO = new ExplainFilterConditionVO();
        List<FieldAndLogicPojo> conditionFieldList = new ArrayList<>();
        List<FieldAttrEntity> fieldList = new ArrayList<>();
        try {
            //部门单选、部门多选限定返回字段条件只有部门名称
            if (Objects.equals(explainFilterConditionDTO.getFieldType(), FieldTypeEnum.DEPT.getType()) || Objects.equals(explainFilterConditionDTO.getFieldType(), FieldTypeEnum.DEPT_GROUP.getType())){
                FieldAttrEntity dept = new FieldAttrEntity();
                dept.setAttr(FieldTypeEnum.DEPT_NAME.getAlias());
                dept.setFieldType(FieldTypeEnum.DEPT_NAME.getType());
                dept.setAttrName(FieldTypeEnum.DEPT_NAME.getDescription());
                fieldList.add(dept);
            }else {
                FieldAttrEntity user = new FieldAttrEntity();
                user.setAttr(FieldTypeEnum.USER_NAME.getAlias());
                user.setFieldType(FieldTypeEnum.USER_NAME.getType());
                user.setAttrName(FieldTypeEnum.USER_NAME.getDescription());
                fieldList.add(user);
                FieldAttrEntity dept = new FieldAttrEntity();
                dept.setAttr(FieldTypeEnum.DEPT_NAME.getAlias());
                dept.setFieldType(FieldTypeEnum.DEPT_NAME.getType());
                dept.setAttrName(FieldTypeEnum.DEPT_NAME.getDescription());
                fieldList.add(dept);
                FieldAttrEntity role = new FieldAttrEntity();
                role.setAttr(FieldTypeEnum.ROLE_NAME.getAlias());
                role.setFieldType(FieldTypeEnum.ROLE_NAME.getType());
                role.setAttrName(FieldTypeEnum.ROLE_NAME.getDescription());
                fieldList.add(role);
            }
            Iterator<FieldAttrEntity> iterator = fieldList.iterator();
            while (iterator.hasNext()){
                FieldAttrEntity fieldAttrEntity = iterator.next();
                FieldAndLogicPojo conditionField = getOptionalFieldAndLogic(fieldAttrEntity);
                //封装角色信息
                if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.ROLE_NAME.getType())){
                    HashMap<String, Object> hashMap = new HashMap<>();
                    hashMap.put("corpid", explainFilterConditionDTO.getCorpid());
                    hashMap.put("del", 0);
                    List<RoleEntity> roles = roleModel.findEntitys(hashMap);
                    List<ItemPoJo> itemPoJoList =  new ArrayList<>();
                    for (RoleEntity item : roles) {
                        ItemPoJo itemPoJo = new ItemPoJo();
                        itemPoJo.setText(item.getRoleName());
                        itemPoJo.setValue(item.getId());
                        itemPoJoList.add(itemPoJo);
                    }
                    conditionField.setItems(itemPoJoList);
                }
                conditionFieldList.add(conditionField);
            }
            explainFilterConditionVO.setExplainList(conditionFieldList);
        } catch (Exception e) {
            LOG.error("paasFormExplainService.optionalRangeConditionList 执行出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return explainFilterConditionVO;
    }

    @Override
    public LinkFormItemVO workflowLinkFormList(LinkFormItemDTO linkFormItemDTO) throws XbbException {
        LinkFormItemVO linkFormItemVO = new LinkFormItemVO();
        String corpid = linkFormItemDTO.getCorpid();
        Integer linkBusinessType = linkFormItemDTO.getLinkBusinessType();
        Integer businessType = linkFormItemDTO.getBusinessType();
        Long dataId = linkFormItemDTO.getDataId();
        Long taskId = linkFormItemDTO.getTaskId();
        SheetTypeEnum sheetTypeEnum = SheetTypeEnum.getByBusinessType(linkBusinessType);
        boolean sheetFlag = SheetTypeEnum.validateSheet(sheetTypeEnum);
        boolean paymentSheetFlag = PaymentSheetTypeEnum.validateSheet(sheetTypeEnum);
        boolean paySheetFlag = PaySheetTypeEnum.validateSheet(sheetTypeEnum);
        List<String> paymentSheetTypeList = null;
        List<String> paySheetTypeList = null;
        PaasFormEntityExt linkForm;
        if (paymentSheetFlag) {
            if (Objects.equals(sheetTypeEnum, SheetTypeEnum.WRITE_OFF)) {
                paymentSheetTypeList = Arrays.asList(SheetTypeEnum.WRITE_OFF.getCode(), PaymentSheetTypeEnum.RED_WRITE_OFF.getCode(), PaymentSheetTypeEnum.BAD_PAYMENT.getCode());
            } else if (Objects.equals(sheetTypeEnum, SheetTypeEnum.WRITE_OFF_PREPAYMENT)) {
                paymentSheetTypeList = Arrays.asList(PaymentSheetTypeEnum.WRITE_OFF_PREPAYMENT.getCode(), PaymentSheetTypeEnum.RED_WRITE_OFF_PREPAYMENT.getCode());
            }
            linkForm = paasFormModel.getByBusinessType(XbbRefTypeEnum.PAYMENT_SHEET.getCode(), corpid);
        } else if ( paySheetFlag ) {
            if (Objects.equals(sheetTypeEnum, SheetTypeEnum.WRITE_OFF_PAY)) {
                paySheetTypeList = Arrays.asList(PaySheetTypeEnum.WRITE_OFF_PAY.getCode(), PaySheetTypeEnum.RED_WRITE_OFF_PAY.getCode(), PaySheetTypeEnum.BAD_PAY.getCode());
            } else if (Objects.equals(sheetTypeEnum, SheetTypeEnum.WRITE_OFF_PREPAY)) {
                paySheetTypeList = Arrays.asList(PaySheetTypeEnum.WRITE_OFF_PREPAY.getCode(), PaySheetTypeEnum.RED_WRITE_OFF_PREPAY.getCode());
            }
            linkForm = paasFormModel.getByBusinessType(XbbRefTypeEnum.PAY_SHEET.getCode(), corpid);
        } else {
            linkForm = paasFormModel.getByBusinessType(linkBusinessType, corpid);
        }
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(linkForm.getId(), corpid);
        Long appId = paasFormExplainEntity.getAppId();
        Long menuId = paasFormExplainEntity.getMenuId();
        Long formId = paasFormExplainEntity.getFormId();
        saasAddHelp.handleFormEntity(linkForm, linkFormItemDTO.getSaasMark(), linkFormItemDTO.getBusinessType());
        String formName = linkForm.getName();
        RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(businessType);
        FormDataListDTO formDataListDTO = new FormDataListDTO();
        BeanUtil.copyProperties(linkFormItemDTO, formDataListDTO);
        formDataListDTO.setAppId(appId);
        formDataListDTO.setMenuId(menuId);
        formDataListDTO.setBusinessType(linkBusinessType);
        List<PaasFormDataEntityExt> formDataList = new ArrayList<>();
        List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        boolean editFlag = dataId != null && !Objects.equals(dataId, 0L);
        SaasSpecialParamPojo saasSpecialParamPojo = linkFormItemDTO.getSaasSpecialParamPojo();
        //关联新建红冲发票特殊处理
        if (Objects.equals(XbbRefTypeEnum.INVOICE.getCode(), linkBusinessType)) {
            if (saasSpecialParamPojo != null && Objects.equals(IsRedEnum.RED.getCode(), saasSpecialParamPojo.getFromRed())) {
                linkFormHandleRedInvoiceExplain(explainList);
                //关联新建红冲发票不走流程获取字段解释
                linkForm.setIsProcessForm(BasicConstant.ZERO);
            }
        }
        // 过滤下不可见字段
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(linkFormItemDTO, handlerExplainDTO, false);
        handlerExplainDTO.setExplainList(explainList);
        handlerExplainDTO.setPaasFormEntityExt(linkForm);
        HandlerExplainVO handlerExplainVO = formDataAddFormExplainHandlerName.handleExplain(handlerExplainDTO);
        if (handlerExplainVO == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
        }
        explainList = handlerExplainVO.getHeadList();
        if (sheetFlag) {
            fundHelp.handlePaymentSheet(!editFlag, sheetTypeEnum, explainList, corpid, linkFormItemDTO.getDistributorMark());
        }
        RedundantTemplateTypeEnum linkTypeEnum = RedundantTemplateTypeEnum.getByCode(linkBusinessType);
        XbbRefTypeEnum linkXbbRefTypeEnum = XbbRefTypeEnum.getByCode(linkBusinessType);
        analysisExplain(linkTypeEnum, explainList, formDataListDTO);
        List<FieldAttrEntity> showColumnList = getShowColumnList(redundantTemplateTypeEnum, explainList, formDataListDTO, dataId, linkXbbRefTypeEnum);
        Long formDataId = 0L;
        JSONObject dataObject = new JSONObject();
        Long addTime = null;
        if (taskId != null && !Objects.equals(taskId, 0L)) {
//            PaasProcessDataEntity paasProcessDataEntity = paasProcessDataModel.getByTaskId(taskId, corpid);
            WorkflowTransferDataEntity workflowTransferDataEntity = workflowTransferDataModel.getByTaskId(taskId, corpid);
            addTime = workflowTransferDataEntity.getAddTime();
            WorkflowTransferPOJO workflowTransferPOJO = JSON.parseObject(JSON.toJSONString(workflowTransferDataEntity.getData(), SerializerFeature.DisableCircularReferenceDetect), WorkflowTransferPOJO.class);
            if (workflowTransferPOJO != null) {
//                formDataId = paasProcessDataEntity.getFormDataId();
                formDataId = workflowTransferPOJO.getData().getId();
                dataObject = workflowTransferPOJO.getData().getData();
                XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(linkFormItemDTO.getBusinessType());
                JSONArray linkArray = new JSONArray();
                switch (xbbRefTypeEnum) {
                    case CONTRACT:
                        switch (linkXbbRefTypeEnum){
                            case PAYMENT_SHEET:
                                linkArray = dataObject.getJSONArray(ContractEnum.ADD_PAYMENT_SHEET.getAttr());
                                break;
                            case WRITE_OFF_PREPAYMENT:
                                linkArray = dataObject.getJSONArray(ContractEnum.ADD_WRITE_OFF_PREPAYMENT.getAttr());
                                break;
                            case PAYMENT:
                                linkArray = dataObject.getJSONArray(ContractEnum.ADD_PAYMENT.getAttr());
                                break;
                            default:
                                break;
                        }
                        break;
                    case PURCHASE:
                        switch (linkXbbRefTypeEnum){
                            case PAY_SHEET:
                                linkArray = dataObject.getJSONArray(PurchaseEnum.ADD_PAY_SHEET.getAttr());
                                break;
                            case WRITE_OFF_PREPAY:
                                linkArray = dataObject.getJSONArray(PurchaseEnum.ADD_WRITE_OFF_PREPAY.getAttr());
                                break;
                            case PAY_PLAN:
                                linkArray = dataObject.getJSONArray(PurchaseEnum.ADD_PAYPLAN.getAttr());
                                break;
                            default:
                                break;
                        }
                        break;
                    case CUSTOMER_MANAGEMENT:
                        linkArray = dataObject.getJSONArray(CustomerManagementEnum.ADD_CONTACT.getAttr());
                        break;
                    case SUPPLIER:
                        linkArray = dataObject.getJSONArray(SupplierEnum.ADD_SUPPLIER_CONTACT.getAttr());
                        break;
                    default:
                        break;
                }
                if (linkArray != null) {
                    formDataList = JSON.parseArray(JSON.toJSONString(linkArray), PaasFormDataEntityExt.class);
                    checkDataHavaEditAndDelPermission(formDataList, linkBusinessType, linkFormItemDTO, true);
                }
            }
        } else if (editFlag) {
            if (paymentSheetFlag && Objects.nonNull(paymentSheetTypeList)) {
                List<Object> typeList = new ArrayList<>(paymentSheetTypeList);
                ConditionsEntityExt conditions = new ConditionsEntityExt(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr(), null, FieldTypeEnum.TEXT.getType(), ConditionEnum.IN.getSymbol(), typeList);
                formDataListDTO.getConditions().add(conditions);
                ConditionsEntityExt aloneConditions = new ConditionsEntityExt(FieldTypeEnum.SHEET_ALONE.getAlias(), null, FieldTypeEnum.SHEET_ALONE.getType(), ConditionEnum.IN.getSymbol(), Arrays.asList(SheetAloneEnum.NORMAL.getCode(), SheetAloneEnum.PARENT.getCode()));
                formDataListDTO.getConditions().add(aloneConditions);
            } else if (paySheetFlag && Objects.nonNull(paySheetTypeList)){
                List<Object> typeList = new ArrayList<>(paySheetTypeList);
                ConditionsEntityExt conditions = new ConditionsEntityExt(PaySheetEnum.PAY_SHEET_TYPE.getAttr(), null, FieldTypeEnum.TEXT.getType(), ConditionEnum.IN.getSymbol(), typeList);
                formDataListDTO.getConditions().add(conditions);
                ConditionsEntityExt aloneConditions = new ConditionsEntityExt(FieldTypeEnum.SHEET_ALONE.getAlias(), null, FieldTypeEnum.SHEET_ALONE.getType(), ConditionEnum.IN.getSymbol(), Arrays.asList(SheetAloneEnum.NORMAL.getCode(), SheetAloneEnum.PARENT.getCode()));
                formDataListDTO.getConditions().add(aloneConditions);
            }
            if( Objects.equals(linkXbbRefTypeEnum, XbbRefTypeEnum.PAYMENT) && formDataListDTO.getSortMap().isEmpty()){
                Map<String,String> sortMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                sortMap.put("field",PaymentEnum.ESTIMATE_TIME.getAttr());
                sortMap.put("sort","asc");
                formDataListDTO.setSortMap(sortMap);
            } else if (  Objects.equals(linkXbbRefTypeEnum, XbbRefTypeEnum.PAY_PLAN) && formDataListDTO.getSortMap().isEmpty() ) {
                Map<String,String> sortMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                sortMap.put("field",PayPlanEnum.ESTIMATE_TIME.getAttr());
                sortMap.put("sort","asc");
                formDataListDTO.setSortMap(sortMap);
            }
            formDataListDTO.setDel(DelEnum.NORMAL.getDel());
            // 不要解析的数据
            formDataListDTO.setFromExport(1);
            formDataListDTO.setSearchSubForm(true);
            PaasFormDataEsListVO formDataEsListVO = paasFormDataService.listByEs(formDataListDTO);
            formDataList = formDataEsListVO.getPaasFormDataESList();
            checkDataHavaEditAndDelPermission(formDataList, linkBusinessType, linkFormItemDTO, false);
        }
        // 获取用户容器
        Map<String, Object> params = BeanUtil.convertBean2Map(linkFormItemDTO, true);
        List<UserEntity> userList = userModel.findEntitys(params);
        if (userList == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.USER_NOT_EXIST);
        }
        Map<String, UserEntity> userMap = new HashMap<>(userList.size());
        userList.forEach((item) -> userMap.put(item.getUserId(), item));
        // 获取部门容器
        params.remove(ParameterConstant.COLUMNS);
        List<DepartmentEntity> departmentList = departmentModel.findEntitys(params);
        if (departmentList == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.DEPT_NOT_EXIST);
        }
        Map<String, DepartmentEntity> departmentMap = new HashMap<>(departmentList.size());
        departmentList.forEach((departmentItem) -> departmentMap.put(departmentItem.getId().toString(), departmentItem));

        ParseSingleRowDataDTO parseSingleRowDataDTO = new ParseSingleRowDataDTO();
        BeanUtil.copyProperties(linkFormItemDTO, parseSingleRowDataDTO);
        parseSingleRowDataDTO.setDepartmentMap(departmentMap);
        parseSingleRowDataDTO.setUserMap(userMap);
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(explainList.size());
        explainList.forEach(item -> {
            explainMap.put(item.getAttr(), item);
        });
        parseSingleRowDataDTO.setExplainMap(explainMap);
        //处理资金负责团队信息
        handleTeam(corpid, formDataList, linkBusinessType, taskId, explainMap, dataObject, businessType, addTime);
        //处理回款单下的子回款单
        handlerLinkSheet(corpid, formDataList, paymentSheetFlag,paySheetFlag, dataId, userMap);
        for (PaasFormDataEntityExt item : formDataList) {
            JSONObject jsonObject = item.getData();
            //加入富文本数据
            richTextService.addRichTextByDataId(item.getId(), item.getCorpid(), item.getFormId(), linkFormItemDTO.getLinkBusinessType(), linkFormItemDTO.getSaasMark(), DelEnum.NORMAL.getDel(), jsonObject);
            Long departmentId = jsonObject.getLong(FieldTypeEnum.DEPARTMENTID.getAlias());
            jsonObject.put(FieldTypeEnum.DEPARTMENTID.getAlias(), Objects.nonNull(departmentId) ? departmentId : item.getDepartmentId());
            parseSingleRowDataDTO.setDataJsonObject(jsonObject);
            ParseSingleRowDataVO parseSingleRowDataVO;
            try {
                parseSingleRowDataVO = formDataLinkAddUpdateGetAnalysisDataHelp.parseSingleRowData(parseSingleRowDataDTO);
                LinkResultDataVO linkResultDataVO = parseSingleRowDataVO.getLinkResultDataVO();
                JSONObject result = parseSingleRowDataVO.getResult();
                // 获取关联数据的信息
                if (linkResultDataVO != null && !linkResultDataVO.getLinkData().isEmpty() && !linkResultDataVO.getLinkDataSet().isEmpty()) {
                    FormDataUpdateGetDTO formDataGetDTO = new FormDataUpdateGetDTO();
                    BeanUtil.copyProperties(linkFormItemDTO, formDataGetDTO);
                    linkResultDataVO.setData(result);
                    linkResultDataVO.setExplainMap(explainMap);
                    linkResultDataVO.setUserMap(userMap);
                    linkResultDataVO.setDepartmentMap(departmentMap);
                    linkResultDataVO.setExplainList(explainList);
                    result = formDataLinkDataUpdateGetService.formDataLinkDataGet(formDataGetDTO, linkResultDataVO);
                }
                SaasAnalysisDataDTO saasAnalysisDataDTO = new SaasAnalysisDataDTO();
                BeanUtil.copyProperties(linkFormItemDTO, saasAnalysisDataDTO);
                saasAnalysisDataDTO.setDataId(item.getId());
                saasAnalysisDataDTO.setBusinessType(linkBusinessType);
                // saas特殊格式转换
                saasAnalysisDataDTO.setExplainMap(explainMap);
                saasUpdateHelp.formatData(saasAnalysisDataDTO, result);
                item.setData(result);
                // 兼容一下dataId或id为空的情况
                if (Objects.isNull(item.getId())) {
                    item.setId(item.getDataId());
                } else if (Objects.isNull(item.getDataId())) {
                    item.setDataId(item.getId());
                }
            } catch (XbbException e) {
                LOG.error("paasFormExplainServiceImpl获取关联新建的解释和数据出错", e);
            }
        }

        linkFormItemVO.setFormDataList(formDataList);
        linkFormItemVO.setExplainList(explainList);
        JSONObject linkFormMessage = new JSONObject();
        linkFormMessage.put("appId", appId);
        linkFormMessage.put("menuId", menuId);
        linkFormMessage.put("formId", formId);
        linkFormMessage.put("formName", formName);
        linkFormItemVO.setLinkFormMessage(linkFormMessage);
        linkFormItemVO.setShowColumnList(showColumnList);
        return linkFormItemVO;
    }

    /**
     * 根据规则过滤字段
     *
     * @param clazz                  规则类
     * @param filterExplainByRuleDTO 查询字段列表的条件
     * @param fieldType              规则对应的字段
     * @return
     * @throws XbbException
     */
    public List<FieldAttrEntity> getFilterExplainListByRule(Object clazz, FilterExplainByRuleDTO filterExplainByRuleDTO, Integer fieldType) throws XbbException {
        List<FieldAttrEntity> jsonArray = new ArrayList<>();
        try {
            List<FieldAttrEntity> explainJsonArray;
            String corpid = filterExplainByRuleDTO.getCorpid();
            Long formId = filterExplainByRuleDTO.getFormId();
            Integer fieldBusinessType = filterExplainByRuleDTO.getLinkedType();
            LinkInfoPojo linkInfoPojo = filterExplainByRuleDTO.getLinkInfo();
            Integer saasMark = filterExplainByRuleDTO.getSaasMark();
            Integer businessType = filterExplainByRuleDTO.getBusinessType();
            Long linkFormId = null;
            if (Objects.nonNull(linkInfoPojo)) {
                fieldBusinessType = linkInfoPojo.getLinkBusinessType();
                linkFormId = linkInfoPojo.getLinkFormId();
                saasMark = linkInfoPojo.getLinkSaasMark();
            }
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), filterExplainByRuleDTO.getBusinessType())) {
                WorkOrderExplainEntityExt workOrderExplainEntityExt = workOrderExplainModel.getByFormId(formId, corpid);
                if (workOrderExplainEntityExt == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                }
                explainJsonArray = JSON.parseArray(workOrderExplainEntityExt.getExplains(), FieldAttrEntity.class);
            } else {
                PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
                if (paasFormExplainEntity == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                }
                explainJsonArray = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            }
            Set<Integer> fieldTypeSet = new HashSet<>(); // 符合映射规则的可作为联动字段的类型
            FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
            // 图片和附件暂不支持
            if (fieldTypeEnum != null && ReflectHelper.exist(clazz, fieldTypeEnum.getAlias().toUpperCase())
                    && (!Objects.equals(fieldTypeEnum.getType(), FieldTypeEnum.UPLOAD.getType()) || !Objects.equals(fieldTypeEnum.getType(), FieldTypeEnum.IMAGE.getType()))) {
                Integer[] array = (Integer[]) ReflectHelper.valueGet(clazz, fieldTypeEnum.getAlias().toUpperCase());
                for (Integer integer : array) {
                    fieldTypeSet.add(integer);
                }
            }

            for (FieldAttrEntity fieldAttrEntity : explainJsonArray) {

                Integer showType = fieldAttrEntity.getShowType();
                Boolean invisible = Objects.nonNull(fieldAttrEntity.getShowType()) && (ShowTypeEnum.LIST.getCode() == showType || ShowTypeEnum.DETAIL.getCode() == showType
                        || ShowTypeEnum.LIST_DETAIL.getCode() == showType || ShowTypeEnum.NONE.getCode() == showType);
                if (invisible || Objects.equals(0, fieldAttrEntity.getIsOpen()) || Objects.equals(2, fieldAttrEntity.getIsOpen())) {
                    continue;
                }
                if (fieldTypeSet.contains(fieldAttrEntity.getFieldType())) {
                    boolean  isLinkData = Objects.equals(FieldTypeEnum.LINK_DATA.getType(), fieldAttrEntity.getFieldType()) || Objects.equals(FieldTypeEnum.LINK_DATA_MULTI.getType(), fieldAttrEntity.getFieldType());
                    if (isLinkData) {
                        LinkInfoPojo linkInfoPojo1 = fieldAttrEntity.getLinkInfo();
                        businessType = linkInfoPojo1.getLinkBusinessType();
                        formId = linkInfoPojo1.getLinkFormId();
                    }
                    if (Objects.equals(XbbRefTypeEnum.PRODUCT.getCode(), businessType) && Objects.equals(ProductEnum.STOCK_NOTIFY.getAttr(), fieldAttrEntity.getAttr())) {
                        // 不要产品的预警提醒
                        continue;
                    }
                    if (FilterExplainUtil.filterField(fieldAttrEntity, saasMark, businessType, fieldBusinessType, true, formId, linkFormId, fieldType)) {
                        continue;
                    }
                    jsonArray.add(fieldAttrEntity);
                }
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormExplainServiceImpl根据规则过滤字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return jsonArray;
    }

    /**
     * 根据规则过滤字段
     *
     * @param clazz                  规则类
     * @param filterExplainByRuleDTO 查询字段列表的条件
     * @param fieldType              规则对应的字段
     * @return
     * @throws XbbException
     */
    public List<FieldAttrEntity> getConvertFilterExplainListByRule(Object clazz, FilterExplainByRuleDTO filterExplainByRuleDTO, Integer fieldType) throws XbbException {
        List<FieldAttrEntity> jsonArray = new ArrayList<>();
        try {
            String corpid = filterExplainByRuleDTO.getCorpid();
            Long formId = filterExplainByRuleDTO.getFormId();
            Integer fieldBusinessType = filterExplainByRuleDTO.getLinkedType();
            LinkInfoPojo linkInfoPojo = filterExplainByRuleDTO.getLinkInfo();
            Integer saasMark = filterExplainByRuleDTO.getSaasMark();
            Integer businessType = filterExplainByRuleDTO.getBusinessType();
            String attr = filterExplainByRuleDTO.getLinkAttr();
            boolean isSubForm = StringUtil.isNotEmpty(attr) && attr.startsWith("subForm_");
            Long linkFormId = null;
            if (Objects.nonNull(linkInfoPojo)) {
                fieldBusinessType = linkInfoPojo.getLinkBusinessType();
                linkFormId = linkInfoPojo.getLinkFormId();
                saasMark = linkInfoPojo.getLinkSaasMark();
            }
            PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
            if (paasFormExplainEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            List<FieldAttrEntity> explainJsonArray = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            Set<Integer> fieldTypeSet = new HashSet<>();
            FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
            if (fieldTypeEnum != null && ReflectHelper.exist(clazz, fieldTypeEnum.getAlias().toUpperCase())
                    && (!Objects.equals(fieldTypeEnum.getType(), FieldTypeEnum.UPLOAD.getType()) || !Objects.equals(fieldTypeEnum.getType(), FieldTypeEnum.IMAGE.getType()))) {
                Integer[] array = (Integer[]) ReflectHelper.valueGet(clazz, fieldTypeEnum.getAlias().toUpperCase());
                for (Integer integer : array) {
                    fieldTypeSet.add(integer);
                }
            }
            if (Objects.equals(fieldType, FieldTypeEnum.LABEL.getType())) {
                // 标签字段只能联动标签字段
                fieldTypeSet.add(FieldTypeEnum.LABEL.getType());
            }
            List<String> attrs = new ArrayList<>();
            if (Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), fieldBusinessType)) {
                attrs.add(CustomerManagementEnum.CUSTOMER_STAGE.getAttr());
                attrs.add(CustomerManagementEnum.DISTRIBUTION_DATE.getAttr());
                attrs.add(CustomerManagementEnum.BACK_PUBLIC_DATE.getAttr());
                attrs.add(CustomerManagementEnum.LAST_CONNECT_TIME.getAttr());
                attrs.add(CustomerManagementEnum.SCORE.getAttr());
            }
            for (FieldAttrEntity fieldAttrEntity : explainJsonArray) {
                Integer attrFieldType = fieldAttrEntity.getFieldType();
                Integer showType = fieldAttrEntity.getShowType();
                Boolean invisible = Objects.nonNull(fieldAttrEntity.getShowType()) && (ShowTypeEnum.LIST.getCode() == showType || ShowTypeEnum.DETAIL.getCode() == showType
                        || ShowTypeEnum.LIST_DETAIL.getCode() == showType || ShowTypeEnum.NONE.getCode() == showType);
                if (invisible || Objects.equals(0, fieldAttrEntity.getIsOpen())) {
                    continue;
                }
                if (attrs.contains(fieldAttrEntity.getAttr())) {
                    continue;
                }
                if (ExplainUtil.isSubFormNoSelectProduct(attrFieldType) && Objects.nonNull(fieldAttrEntity.getSubForm())) {
                    if (!isSubForm) {
                        // 子表单子字段只能和子表单的子字段联动
                        continue;
                    }
                    List<? extends FieldAttrEntity> items = fieldAttrEntity.getSubForm().getItems();
                    for (FieldAttrEntity item : items) {
                        if (!fieldTypeSet.contains(item.getFieldType())) {
                            continue;
                        }
                        boolean subIsLinkData = Objects.equals(FieldTypeEnum.LINK_DATA.getType(), item.getFieldType());
                        if (subIsLinkData) {
                            LinkInfoPojo linkInfoPojo1 = item.getLinkInfo();
                            businessType = linkInfoPojo1.getLinkBusinessType();
                            formId = linkInfoPojo1.getLinkFormId();
                        }
                        if (FilterExplainUtil.filterField(item, saasMark, businessType, fieldBusinessType, true, formId, linkFormId, fieldType)) {
                            continue;
                        }
                        FieldAttrEntity subEntity = new FieldAttrEntity();
                        subEntity.setAttr(fieldAttrEntity.getAttr() + "." + item.getAttr());
                        subEntity.setAttrName(fieldAttrEntity.getAttrName() + "." + item.getAttrName());
                        subEntity.setFieldType(fieldAttrEntity.getFieldType());
                        jsonArray.add(subEntity);
                    }
                    continue;
                }
                if (fieldTypeSet.contains(attrFieldType)) {
                    if (Objects.equals(fieldAttrEntity.getSaasAttr(), "extensionField")) {
                        // 拓展字段不联动
                        continue;
                    }
                    if (isSubForm) {
                        // 子表单子字段，只能联动子表单的子字段
                        continue;
                    }
                    boolean  isLinkData = Objects.equals(FieldTypeEnum.LINK_DATA.getType(), fieldAttrEntity.getFieldType());
                    if (isLinkData) {
                        LinkInfoPojo linkInfoPojo1 = fieldAttrEntity.getLinkInfo();
                        businessType = linkInfoPojo1.getLinkBusinessType();
                        formId = linkInfoPojo1.getLinkFormId();
                    }
                    if (FilterExplainUtil.filterField(fieldAttrEntity, saasMark, businessType, fieldBusinessType, true, formId, linkFormId, fieldType)) {
                        continue;
                    }
                    FieldAttrEntity entity = new FieldAttrEntity();
                    entity.setAttr(fieldAttrEntity.getAttr());
                    entity.setAttrName(fieldAttrEntity.getAttrName());
                    entity.setFieldType(fieldAttrEntity.getFieldType());
                    jsonArray.add(entity);
                }
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("线索转换已有客户\\字段映射获取联动字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return jsonArray;
    }

    /**
     * 根据规则过滤字段且包含子字段
     *
     * @param clazz                  规则类
     * @param filterExplainByRuleDTO 查询字段列表的条件
     * @param fieldType              规则对应的字段
     * @param block 不可设置子表单的字段，如：日期，多选相关字段
     * @param condition 是否是条件，如果是操作的话，关联数据必须是表单id一致
     * @return
     * @throws XbbException
     */
    public List<FieldAttrEntity> getFieldListByRuleIncludeSubField(Object clazz, FilterExplainByRuleDTO filterExplainByRuleDTO, Integer fieldType, boolean block, boolean condition) throws XbbException {
        List<FieldAttrEntity> jsonArray = new ArrayList<>();
        try {
            List<FieldAttrEntity> explainJsonArray;
            String corpid = filterExplainByRuleDTO.getCorpid();
            Long formId = filterExplainByRuleDTO.getFormId();
            Integer businessType = filterExplainByRuleDTO.getBusinessType();
            Integer saasMark = filterExplainByRuleDTO.getSaasMark();
            LinkInfoPojo linkInfoPojo = filterExplainByRuleDTO.getLinkInfo();
            Integer fieldBusinessType = filterExplainByRuleDTO.getLinkedType();
            Long linkFormId = null;
            if (Objects.nonNull(linkInfoPojo)) {
                fieldBusinessType = linkInfoPojo.getLinkBusinessType();
                linkFormId = linkInfoPojo.getLinkFormId();
                saasMark = linkInfoPojo.getLinkSaasMark();
            }
            boolean isDataId = Objects.equals(FieldTypeEnum.DATAID.getType(), fieldType);
            Integer distributorMark = DistributorMarkEnum.OTHER.getCode();
            RuleTargetPojo ruleTargetPojo = filterExplainByRuleDTO.getTarget();
            if (isDataId && Objects.nonNull(ruleTargetPojo)) {
                fieldBusinessType = ruleTargetPojo.getLinkBusinessType();
                linkFormId = ruleTargetPojo.getFormId();
                saasMark = ruleTargetPojo.getLinkSaasMark();
            }
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), businessType)) {
                WorkOrderExplainEntityExt workOrderExplainEntityExt = workOrderExplainModel.getByFormId(formId, corpid);
                if (workOrderExplainEntityExt == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                }
                explainJsonArray = JSON.parseArray(workOrderExplainEntityExt.getExplains(), FieldAttrEntity.class);
            } else {
                PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
                if (paasFormExplainEntity == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                }
                explainJsonArray = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                distributorMark = paasFormExplainEntity.getDistributorMark();
            }
            FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
            String alias = fieldTypeEnum.getAlias().toUpperCase();
            Set<Integer> fieldTypeSet = new HashSet<>();
            if (fieldTypeEnum != null && ReflectHelper.exist(clazz, alias)) {
                Integer[] array = (Integer[]) ReflectHelper.valueGet(clazz, alias);
                for (Integer integer : array) {
                    fieldTypeSet.add(integer);
                }
            }

            Map<Integer, List<String>> fieldBlockMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            fieldBlockMap.put(XbbRefTypeEnum.PAYMENT_SHEET.getCode(), Arrays.asList(PaymentSheetEnum.PAY_METHOD.getAttr(), PaymentSheetEnum.FUND_ACCOUNT.getAttr()));
            // 是否为联系人
            boolean isContact = Objects.equals(XbbRefTypeEnum.CONTACT.getCode(), businessType) && Objects.equals(DistributorMarkEnum.OTHER.getCode(), distributorMark);
            if (isContact) {
                fieldBlockMap.put(XbbRefTypeEnum.CONTACT.getCode(), Arrays.asList(ContactEnum.AVATAR.getAttr()));
            }
            for (FieldAttrEntity fieldAttrEntity : explainJsonArray) {
                if (fieldBlockMap.containsKey(businessType)) {
                    List<String> fieldBlockList = fieldBlockMap.get(businessType);
                    if (fieldBlockList.contains(fieldAttrEntity.getAttr())) {
                        continue;
                    }
                }
                Integer showType = fieldAttrEntity.getShowType();
                Boolean invisible = Objects.nonNull(fieldAttrEntity.getShowType()) && (ShowTypeEnum.LIST.getCode() == showType || ShowTypeEnum.DETAIL.getCode() == showType
                        || ShowTypeEnum.LIST_DETAIL.getCode() == showType || ShowTypeEnum.NONE.getCode() == showType);
                if (invisible || Objects.equals(0, fieldAttrEntity.getIsOpen()) || Objects.equals(fieldAttrEntity.getIsOpen(), 2)) {
                    continue;
                }
                boolean  isLinkData = Objects.equals(FieldTypeEnum.LINK_DATA.getType(), fieldAttrEntity.getFieldType()) || Objects.equals(FieldTypeEnum.LINK_DATA_MULTI.getType(), fieldAttrEntity.getFieldType());
                if (isLinkData) {
                    // 判断用户所选的字段和字段关联表单是否是同一个表单
                    LinkInfoPojo linkInfoPojo1 = fieldAttrEntity.getLinkInfo();
                    if (FilterExplainUtil.filterField(fieldAttrEntity, saasMark, linkInfoPojo1.getLinkBusinessType(), fieldBusinessType, condition, linkInfoPojo1.getLinkFormId(), linkFormId, fieldType)) {
                        // 过滤掉字段
                        continue;
                    }
                } else if (Objects.equals(FieldTypeEnum.LINK_BUSINESS_SINGLE.getType(), fieldAttrEntity.getFieldType())) {
                    // 判断用户所选的字段和字段是否是同一个业务
                    if (FilterExplainUtil.filterField(fieldAttrEntity, saasMark, fieldAttrEntity.getLinkedType(), fieldBusinessType, condition, null, linkFormId, fieldType)) {
                        // 过滤掉字段
                        continue;
                    }
                }
                if (Objects.equals(FieldTypeEnum.SUB_FORM.getType(), fieldAttrEntity.getFieldType()) && !block) {
                    List<? extends FieldAttrEntity> subFieldList = fieldAttrEntity.getSubForm().getItems();
                    for (FieldAttrEntity item : subFieldList) {
                        // 字段回收站处理
                        if (Objects.equals(item.getIsOpen(), 2)) {
                            continue;
                        }
                        if (fieldTypeSet.contains(item.getFieldType())) {
                            isLinkData = Objects.equals(FieldTypeEnum.LINK_DATA.getType(), item.getFieldType()) || Objects.equals(FieldTypeEnum.LINK_DATA_MULTI.getType(), item.getFieldType());
                            if (isLinkData) {
                                LinkInfoPojo linkInfoPojo1 = item.getLinkInfo();
                                // 判断用户所选的字段和字段关联表单是否是同一个表单
                                if (FilterExplainUtil.filterField(item, saasMark, linkInfoPojo1.getLinkBusinessType(), fieldBusinessType, condition, linkInfoPojo1.getLinkFormId(), linkFormId, fieldType)) {
                                    // 过滤掉字段
                                    continue;
                                }
                            }

                            item.setAttrName(fieldAttrEntity.getAttrName() + "." + item.getAttrName());
                            item.setAttr(fieldAttrEntity.getAttr() + "." + item.getAttr());
                            jsonArray.add(item);
                        }
                    }
                } else if (fieldTypeSet.contains(fieldAttrEntity.getFieldType())) {
                    jsonArray.add(fieldAttrEntity);
                }
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormExplainServiceImpl根据规则过滤字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return jsonArray;
    }





    /**
     * 入库单、出库单不需要返回系统关联字段
     *
     * @param list
     * @param fieldType
     * @param businessType
     */
    private void removeLinkBusiness(List<FieldAttrEntity> list, Integer fieldType, Integer businessType) {
        Boolean isTrue = Objects.equals(XbbRefTypeEnum.INSTOCK.getCode(), businessType) || Objects.equals(XbbRefTypeEnum.OUTSTOCK.getCode(), businessType);
        if (CollectionsUtil.isNotEmpty(list) && isTrue) {
            Iterator<FieldAttrEntity> iterator = list.iterator();
            while (iterator.hasNext()) {
                FieldAttrEntity fieldAttrEntity = iterator.next();
                if (Objects.equals(FieldTypeEnum.LINK_BUSINESS_SINGLE.getType(), fieldAttrEntity.getFieldType())) {
                    iterator.remove();
                    continue;
                }
            }
        }
    }

    /**
     * @param redundantTemplateTypeEnum 枚举类
     * @param explainList               字段列表
     * @return void
     * @throws XbbException 业务异常
     * @author 吴峰
     * @date 2019/4/2 17:22
     */
    private void analysisExplain(RedundantTemplateTypeEnum redundantTemplateTypeEnum, List<FieldAttrEntity> explainList, FormDataListDTO formDataListDTO) {
        List<String> unableEditMemo= Arrays.asList(I18nMessageUtil.getMessage(StringConstant.AUTO_GEN_FIELD, Locale.US), I18nMessageUtil.getMessage(StringConstant.AUTO_GEN_FIELD, Locale.CHINA));
        Iterator<FieldAttrEntity> fieldAttrEntityIterator = explainList.iterator();
        while (fieldAttrEntityIterator.hasNext()) {
            FieldAttrEntity fieldAttrEntity = fieldAttrEntityIterator.next();
            if (unableEditMemo.contains(fieldAttrEntity.getUnableEditMemo())){
                fieldAttrEntity.setVisible(0);
            }
            String attr = fieldAttrEntity.getAttr();
            List<ItemPoJo> itemList = fieldAttrEntity.getItems();
            switch (redundantTemplateTypeEnum) {
                case PAYMENT:
                    if (Objects.nonNull(itemList) && PaymentEnum.STATUS.getAttr().equals(attr)) {
                        Iterator<ItemPoJo> itemPoJoIterator = itemList.iterator();
                        while (itemPoJoIterator.hasNext()) {
                            ItemPoJo itemPoJo = itemPoJoIterator.next();
                            if (!PaymentStatusEnum.UN_RECEIVABLES.getCode().equals(itemPoJo.getValue())) {
                                itemPoJo.setShowType(ShowTypeEnum.LIST_DETAIL.getCode());
                            } else {
                                itemPoJo.setShowType(ShowTypeEnum.ALL.getCode());
                            }
                        }
                    }
                    break;
                case PAY_PLAN:
                    if (Objects.nonNull(itemList) && PayPlanEnum.STATUS.getAttr().equals(attr)) {
                        Iterator<ItemPoJo> itemPoJoIterator = itemList.iterator();
                        while (itemPoJoIterator.hasNext()) {
                            ItemPoJo itemPoJo = itemPoJoIterator.next();
                            if (!PayPlanStatusEnum.UN_RECEIVABLES.getCode().equals(itemPoJo.getValue()) ) {
                                itemPoJo.setShowType(ShowTypeEnum.EXCLUDE_NEW.getCode());
                            } else {
                                itemPoJo.setShowType(ShowTypeEnum.ALL.getCode());
                            }
                        }
                    }
                    if (Objects.equals(PayPlanEnum.BELONGER.getAttr(), fieldAttrEntity.getAttr())) {
                        DefaultAttrPoJo userDefaultAttrPoJo = new DefaultAttrPoJo();
                        userDefaultAttrPoJo.setDefaultType("custom");
                        OptionalRangeEntity optionalRangeEntity = new OptionalRangeEntity();
                        optionalRangeEntity.setEditable(1);
                        optionalRangeEntity.setProperty(FieldTypeEnum.USER.getAlias());
                        optionalRangeEntity.setId(formDataListDTO.getUserId());
                        optionalRangeEntity.setName(formDataListDTO.getLoginUserName());
                        userDefaultAttrPoJo.setDefaultList(Collections.singletonList(optionalRangeEntity));
                        fieldAttrEntity.setDefaultAttr(userDefaultAttrPoJo);
                    }
                    break;
                case PAYMENT_TASK:
                    if (Objects.equals(PaymentTaskEnum.EXECUTOR_TIME.getAttr(), fieldAttrEntity.getAttr())) {
                        SaasParticularAttributePoJo saasParticularAttributePoJo = new SaasParticularAttributePoJo();
                        saasParticularAttributePoJo.setDateLimit(DateTimeUtil.getTodayInt(DateTimeUtil.getInt()) - BasicConstant.ONE);
                        saasParticularAttributePoJo.setLimitType(false);
                        fieldAttrEntity.setSaasParticularAttributePoJo(saasParticularAttributePoJo);
                    }
                    break;
                default:
                    break;
            }

        }
    }

    /**
     * 获取关联新建时展示的列
     *
     * @param redundantTemplateTypeEnum 业务类型枚举
     * @param explainList               解释
     * @return 需要展示的列
     */
    private List<FieldAttrEntity> getShowColumnList(RedundantTemplateTypeEnum redundantTemplateTypeEnum, List<FieldAttrEntity> explainList, FormDataListDTO formDataListDTO, Long dataId, XbbRefTypeEnum linkTypeEnum) {
        Iterator<FieldAttrEntity> it = explainList.iterator();
        List<FieldAttrEntity> showColumnList = new ArrayList<>();
        List<ConditionsEntityExt> conditions = new ArrayList<>();
        switch (redundantTemplateTypeEnum) {
            case CUSTOMER:
                conditions.add(EsUtil.packageContions(ContactEnum.CUSTOMER_NAME.getAttr(), Collections.singletonList(dataId), ConditionEnum.EQUAL, ContactEnum.CUSTOMER_NAME.getFieldType()));
                break;
            case SUPPLIER:
                conditions.add(EsUtil.packageContions(SupplierContactEnum.SUPPLIER_ID.getAttr(), Collections.singletonList(dataId), ConditionEnum.EQUAL, SupplierContactEnum.SUPPLIER_ID.getFieldType()));
                break;
            case CONTRACT:
            case PAYMENT:
                switch (linkTypeEnum) {
                    case PAYMENT_SHEET:
                    case WRITE_OFF_PREPAYMENT:
                        conditions.add(EsUtil.packageContions(PaymentSheetEnum.CONTRACT.getAttr(), Collections.singletonList(dataId), ConditionEnum.EQUAL, PaymentSheetEnum.CONTRACT.getFieldType()));
                        break;
                 default:
                        conditions.add(EsUtil.packageContions(PaymentEnum.CONTRACT.getAttr(), Collections.singletonList(dataId), ConditionEnum.EQUAL, PaymentEnum.CONTRACT.getFieldType()));
                        break;
                }
                break;
            case PAY_PLAN:
            case PURCHASE:
                switch (linkTypeEnum) {
                    case PAY_SHEET:
                    case WRITE_OFF_PREPAY:
                        conditions.add(EsUtil.packageContions(PaySheetEnum.LINK_PURCHASE.getAttr(), Collections.singletonList(dataId), ConditionEnum.EQUAL, PaySheetEnum.LINK_PURCHASE.getFieldType()));
                        break;
                    default:
                        conditions.add(EsUtil.packageContions(PayPlanEnum.LINK_PURCHASE.getAttr(), Collections.singletonList(dataId), ConditionEnum.EQUAL, PayPlanEnum.LINK_PURCHASE.getFieldType()));
                        break;
                }
                break;
            default:
                break;
        }
        formDataListDTO.setConditions(conditions);
        while (it.hasNext()) {
            FieldAttrEntity fieldAttrEntity = it.next();
            String attr = fieldAttrEntity.getAttr();
            switch (redundantTemplateTypeEnum) {
                case CUSTOMER:
                case DISTRIBUTOR_MANAGEMENT:
                    // 客户新建页需要显示的联系人列
                    if (Objects.equals(attr, ContactEnum.NAME.getAttr()) || Objects.equals(attr, ContactEnum.PHONE.getAttr())) {
                        showColumnList.add(fieldAttrEntity);
                    }
                    // 客户里新建联系人去掉关联客户
                    if (Objects.equals(attr, ContactEnum.CUSTOMER_NAME.getAttr())) {
                        it.remove();
                    }
                    break;
                case SUPPLIER:
                    // 供应商联系人新建页需要显示的联系人列
                    if (Objects.equals(attr, SupplierContactEnum.NAME.getAttr()) || Objects.equals(attr, SupplierContactEnum.PHONE.getAttr())) {
                        showColumnList.add(fieldAttrEntity);
                    }
                    // 供应商里新建联系人去掉关联供应商
                    if (Objects.equals(attr, SupplierContactEnum.SUPPLIER_ID.getAttr())) {
                        it.remove();
                    }
                    break;
                case CONTRACT:
                case PAYMENT:
                    switch (linkTypeEnum) {
                        case WRITE_OFF_PREPAYMENT:
                            // 核销预收款显示列
                            if (Objects.equals(attr, PaymentSheetEnum.WRITE_OFF_AMOUNT.getAttr()) || Objects.equals(attr, PaymentSheetEnum.BELONG_ID.getAttr()) || Objects.equals(attr, PaymentSheetEnum.PAYMENT_TIME.getAttr())) {
                                if ( Objects.equals(attr, PaymentSheetEnum.SHEET_NO.getAttr()) ) {
                                    fieldAttrEntity.setParentAttr(ContractEnum.ADD_WRITE_OFF_PREPAYMENT.getAttr());
                                }
                                if ( Objects.equals(attr, PaymentSheetEnum.BELONG_ID.getAttr()) ) {
                                    fieldAttrEntity.setMultiple(0);
                                }
                                showColumnList.add(fieldAttrEntity);
                            }
                            // 去掉关联客户
                            if (Objects.equals(attr, PaymentSheetEnum.CUSTOMER_ID.getAttr())||Objects.equals(attr, PaymentSheetEnum.CONTRACT.getAttr())){
                                fieldAttrEntity.setVisible(0);
                            }
                            if (Objects.equals(attr, PaymentSheetEnum.PAYMENT.getAttr()) || Objects.equals(attr, PaymentSheetEnum.PAYMENT_TASK.getAttr())) {
                                it.remove();
                            }
                            break;
                        case PAYMENT_SHEET:
                            // 合同新建页需要显示的回款列
                            if (Objects.equals(attr, PaymentSheetEnum.SHEET_NO.getAttr()) || Objects.equals(attr, PaymentSheetEnum.AMOUNT.getAttr()) || Objects.equals(attr, PaymentSheetEnum.FUND_ACCOUNT.getAttr())
                                    ||Objects.equals(attr, PaymentSheetEnum.PAYMENT_TIME.getAttr())
                            ) {
                                if ( Objects.equals(attr, PaymentSheetEnum.SHEET_NO.getAttr()) ) {
                                    fieldAttrEntity.setParentAttr(ContractEnum.ADD_PAYMENT_SHEET.getAttr());
                                }
                                if ( Objects.equals(attr, PaymentSheetEnum.BELONG_ID.getAttr()) ) {
                                    fieldAttrEntity.setMultiple(0);
                                }
                                showColumnList.add(fieldAttrEntity);
                            }
                            if (Objects.equals(attr, PaymentSheetEnum.CUSTOMER_ID.getAttr())||Objects.equals(attr, PaymentSheetEnum.CONTRACT.getAttr())){
                                fieldAttrEntity.setVisible(0);
                            }
                            // 合同里新建回款去掉
                            if (Objects.equals(attr, PaymentSheetEnum.PAYMENT.getAttr()) || Objects.equals(attr, PaymentSheetEnum.PAYMENT_TASK.getAttr())) {
                                it.remove();
                            }
                            break;
                        default:
                            // 合同新建页需要显示的回款列
                            if (Objects.equals(attr, PaymentEnum.PAYMENT_NO.getAttr()) || Objects.equals(attr, PaymentEnum.AMOUNT.getAttr()) || Objects.equals(attr, PaymentEnum.ESTIMATE_TIME.getAttr()) || Objects.equals(attr, PaymentEnum.STATUS.getAttr())
                                    || Objects.equals(attr, PaymentEnum.PAYMENT_TYPE.getAttr()) || Objects.equals(attr, PaymentEnum.MEMO.getAttr())) {
                                if (Objects.equals(attr, PaymentEnum.PAYMENT_NO.getAttr())) {
                                    fieldAttrEntity.setParentAttr(ContractEnum.ADD_PAYMENT.getAttr());
                                }
                                //新增和编辑的处理是不一样的
                                if (Objects.nonNull(dataId)) {
                                    if (Objects.equals(attr, PaymentEnum.PAYMENT_NO.getAttr())) {
                                        fieldAttrEntity.setEditable(BasicConstant.ZERO);
                                    }else if (!Objects.equals(attr, PaymentEnum.MEMO.getAttr())) {
                                        fieldAttrEntity.setEditable(BasicConstant.ZERO);
                                    }
                                }
                                showColumnList.add(fieldAttrEntity);
                            }
                             if (Objects.equals(attr, PaymentEnum.CUSTOMER.getAttr())||Objects.equals(attr, PaymentEnum.CONTRACT.getAttr())){
                                fieldAttrEntity.setVisible(0);
                            }
                            // 合同里新建回款去掉
                            if (Objects.equals(attr, PaymentEnum.ADD_PAYMENT.getAttr())) {
                                it.remove();
                            }
                            break;
                    }
                    break;
                case PAY_PLAN:
                case PURCHASE:
                    switch (linkTypeEnum) {
                        case WRITE_OFF_PREPAY:
                            // 采购合同新建页需要显示的回款列
                            if (Objects.equals(attr, PaySheetEnum.WRITE_OFF_AMOUNT.getAttr()) || Objects.equals(attr, PaySheetEnum.BELONG_ID.getAttr()) || Objects.equals(attr, PaySheetEnum.REAL_PAY_TIME.getAttr())) {
                                if ( Objects.equals(attr, PaySheetEnum.PAY_PLAN_NO.getAttr()) ) {
                                    fieldAttrEntity.setParentAttr(PurchaseEnum.ADD_WRITE_OFF_PREPAY.getAttr());
                                }
                                if ( Objects.equals(attr, PaySheetEnum.BELONG_ID.getAttr()) ) {
                                    fieldAttrEntity.setMultiple(0);
                                }
                                showColumnList.add(fieldAttrEntity);
                            }
                            if (Objects.equals(attr, PaySheetEnum.LINK_SUPPLIER.getAttr())||Objects.equals(attr, PaySheetEnum.LINK_PURCHASE.getAttr())){
                                fieldAttrEntity.setVisible(0);
                            }
                            if (Objects.equals(attr, PaySheetEnum.PAY_PLAN.getAttr())) {
                                it.remove();
                            }
                            break;
                        case PAY_SHEET:
                            // 采购合同新建页需要显示的回款列
                            if (Objects.equals(attr, PaySheetEnum.PAY_PLAN_NO.getAttr()) || Objects.equals(attr, PaySheetEnum.AMOUNT.getAttr()) || Objects.equals(attr, PaySheetEnum.REAL_PAY_TIME.getAttr()) || Objects.equals(attr, PaySheetEnum.FUND_ACCOUNT.getAttr()) ||Objects.equals(attr, PaySheetEnum.BELONG_ID.getAttr())) {
                                if ( Objects.equals(attr, PaySheetEnum.PAY_PLAN_NO.getAttr()) ) {
                                    fieldAttrEntity.setParentAttr(PurchaseEnum.ADD_PAY_SHEET.getAttr());
                                }
                                if ( Objects.equals(attr, PaySheetEnum.BELONG_ID.getAttr()) ) {
                                    fieldAttrEntity.setMultiple(0);
                                }
                                showColumnList.add(fieldAttrEntity);
                            }
                            if (Objects.equals(attr, PaySheetEnum.LINK_SUPPLIER.getAttr())||Objects.equals(attr, PaySheetEnum.LINK_PURCHASE.getAttr())){
                                fieldAttrEntity.setVisible(0);
                            }
                            // 去掉关联供应商等
                            if (Objects.equals(attr, PaySheetEnum.PAY_PLAN.getAttr())) {
                                it.remove();
                            }
                            break;
                        default:
                            // 采购合同新建页需要显示的回款列
                            if (Objects.equals(attr, PayPlanEnum.PAY_PLAN_NO.getAttr()) || Objects.equals(attr, PayPlanEnum.AMOUNT.getAttr()) || Objects.equals(attr, PayPlanEnum.ESTIMATE_TIME.getAttr()) || Objects.equals(attr, PayPlanEnum.STATUS.getAttr()) || Objects.equals(attr, PayPlanEnum.PAY_TYPE.getAttr()) || Objects.equals(attr, PayPlanEnum.MEMO.getAttr())) {
                                if ( Objects.equals(attr, PayPlanEnum.PAY_PLAN_NO.getAttr()) ) {
                                    fieldAttrEntity.setParentAttr(PurchaseEnum.ADD_PAYPLAN.getAttr());
                                }
                                showColumnList.add(fieldAttrEntity);
                            }
                            if (Objects.equals(attr, PayPlanEnum.LINK_SUPPLIER.getAttr())||Objects.equals(attr, PayPlanEnum.LINK_PURCHASE.getAttr())){
                                fieldAttrEntity.setVisible(0);
                            }
                            if (Objects.equals(attr, PayPlanEnum.ADD_PAYPLAN.getAttr())) {
                                it.remove();
                            }
                            break;
                    }
                    break;
                default:
                    break;
            }
        }
        return showColumnList;
    }

    /**
     * 查询镜像配置
     * @param corpid
     * @param alias
     * @author xingxing.xiao
     * @date 2019/12/17 23:02
     */
    private JSONArray getMirrorConfig(String corpid, String alias) throws XbbException {
        if(Objects.equals(corpid,"0")){
            return null;
        }
        // 判断是否标准版(若不是标准版则不使用镜像)
        BasePackageInfoVO basePackageInfoVO = packageService.getBasePackageInfoFromRedis(corpid);
        if (!Objects.equals(basePackageInfoVO.getFeeType(), PackageTypeEnum.STANDARD.getType())) {
            return null;
        }

        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("columns", "id, version_id, is_professional");
        params.put("corpid", corpid);
        params.put("del", 0);
        MirrorCompanyEntity mirrorCompany = mirrorCompanyModel.getMirrorCompany(params);
        if (Objects.isNull(mirrorCompany)) {
            return null;
        }
        if (Objects.equals(mirrorCompany.getIsProfessional(), 1)) {
            // 标准版也不做控制
            return null;
        }
        params.clear();
        params.put("columns", "info, module");
        params.put("versionId", mirrorCompany.getVersionId());
        params.put("module", MirrorModuleEnum.FIELD.getAlias());
        MirrorInfoEntity fieldMirror = mirrorInfoModel.getMirrorModule(params);
        if (Objects.isNull(fieldMirror)) {
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(fieldMirror.getInfo());
        return jsonObject.getJSONArray(alias);
    }

    /**
     * 名称和电话判重设置存一份到表单配置表
     *
     * @param corpid
     * @param formId
     * @param businessType
     * @author xingxing.xiao
     * @date 2019/11/14 14:57
     */
    private void addCustomerFormConfig(String corpid, Long formId, Integer businessType) {
        String nameRepeatConfig = FormConfigEnum.CUSTOMER_NAME_REPEAT_TYPE.getConfig();
        String phoneRepeatConfig = FormConfigEnum.CUSTOMER_PHONE_REPEAT_TYPE.getConfig();
        if (Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
            nameRepeatConfig = FormConfigEnum.CLUE_NAME_REPEAT_TYPE.getConfig();
            phoneRepeatConfig = FormConfigEnum.CLUE_PHONE_REPEAT_TYPE.getConfig();
        }
        String repeatAll = RepeatTypeEnum.REPEAT_ALL.getType().toString();

        // 若有全局配置，则存为全局，其余情况默认为模板内判重
        String configValue = RepeatTypeEnum.REPEAT_SINGLE.getType().toString();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("configIn", Arrays.asList(nameRepeatConfig, phoneRepeatConfig));
        param.put("del", DelEnum.NORMAL.getDel());
        List<FormConfigEntity> formconfigList = formConfigModel.findEntitys(param);
        for (FormConfigEntity configEntity : formconfigList) {
            // 名称判重，任取一个表单配置的值去判断
            if (Objects.equals(configEntity.getConfig(), nameRepeatConfig)) {
                if (Objects.equals(configEntity.getConfigValue(), repeatAll)) {
                    configValue = repeatAll;
                }
                break;
            }
        }
        for (FormConfigEntity configEntity : formconfigList) {
            // 电话判重，任取一个表单配置的值去判断
            if (Objects.equals(configEntity.getConfig(), phoneRepeatConfig)) {
                if (Objects.equals(configEntity.getConfigValue(), repeatAll)) {
                    configValue = repeatAll;
                }
                break;
            }
        }
        FormConfigEntity nameConfigEntity = new FormConfigEntity(corpid, formId, SaasMarkEnum.SAAS.getCode(), businessType, nameRepeatConfig, configValue);
        FormConfigEntity phoneConfigEntity = new FormConfigEntity(corpid, formId, SaasMarkEnum.SAAS.getCode(), businessType, phoneRepeatConfig, configValue);
        List<FormConfigEntity> formConfigEntityList = new ArrayList<>();
        formConfigEntityList.add(nameConfigEntity);
        formConfigEntityList.add(phoneConfigEntity);
        formConfigModel.insertBatch(formConfigEntityList);
    }








    /**
     * 红冲发票关联新建处理解释
     *
     * @param explainList 解释信息
     * @author zhouwq
     * @date 2019/12/3 19:07
     */
    private static void linkFormHandleRedInvoiceExplain(List<FieldAttrEntity> explainList) {
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            if (Objects.equals(fieldAttrEntity.getAttr(), InvoiceEnum.INVOICE_DATE.getAttr())) {
                fieldAttrEntity.setEditable(BasicConstant.ZERO);
                fieldAttrEntity.setVisible(BasicConstant.ZERO);
            }
            if (Objects.equals(fieldAttrEntity.getAttr(), InvoiceEnum.ORIGIN_ID.getAttr())) {
                fieldAttrEntity.setShowType(ShowTypeEnum.EDIT.getCode());
                fieldAttrEntity.setEditable(BasicConstant.ZERO);
            }
            if (Objects.equals(fieldAttrEntity.getAttr(), InvoiceEnum.TOTAL_MONEY.getAttr())) {
                fieldAttrEntity.setAttrName(I18nMessageUtil.getMessage(I18nStringConstant.RED_RUSH_RECEIPT));
            }
            if (Objects.equals(fieldAttrEntity.getAttr(), InvoiceEnum.CUSTOMER_NAME.getAttr())) {
                fieldAttrEntity.setEditable(BasicConstant.ZERO);
            }
            if (Objects.equals(fieldAttrEntity.getAttr(), InvoiceEnum.CONTRACT_ID.getAttr())) {
                fieldAttrEntity.setEditable(BasicConstant.ZERO);
            }
            if (Objects.equals(fieldAttrEntity.getAttr(), InvoiceEnum.PAYMENT_ID.getAttr())) {
                fieldAttrEntity.setEditable(BasicConstant.ZERO);
            }
        }
    }

    public List<PaasFormDataEntityExt> handlerLinkSheet(String corpid, List<PaasFormDataEntityExt> formDataList,Boolean paymentSheetFlag,Boolean paySheetFlag,Long linkId,Map<String, UserEntity> userEntityMap) throws XbbException {
        if ( paymentSheetFlag ) {
            handlerLinkPaymentSheet(XbbRefTypeEnum.PAYMENT_SHEET, corpid, formDataList, linkId, PaymentSheetEnum.CONTRACT.getAttr(), userEntityMap, PaymentSheetEnum.AMOUNT.getAttr(), PaymentSheetEnum.WRITE_OFF_AMOUNT.getAttr(), PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr(), PaymentSheetTypeEnum.WRITE_OFF_PREPAYMENT.getCode(), PaymentSheetTypeEnum.WRITE_OFF.getCode(), PaymentSheetEnum.BELONG_ID.getAttr());
        } else if ( paySheetFlag ) {
            handlerLinkPaymentSheet(XbbRefTypeEnum.PAY_SHEET, corpid, formDataList, linkId, PaySheetEnum.LINK_PURCHASE.getAttr(), userEntityMap, PaySheetEnum.AMOUNT.getAttr(), PaySheetEnum.WRITE_OFF_AMOUNT.getAttr(), PaySheetEnum.PAY_SHEET_TYPE.getAttr(), PaySheetTypeEnum.WRITE_OFF_PREPAY.getCode(), PaySheetTypeEnum.WRITE_OFF_PAY.getCode(), PaySheetEnum.BELONG_ID.getAttr());
        }
        return formDataList;
    }

	public List<PaasFormDataEntityExt> handlerLinkPaymentSheet(XbbRefTypeEnum xbbRefTypeEnum,String corpid, List<PaasFormDataEntityExt> formDataList,Long linkId, String linkBusinessAttr, Map<String, UserEntity> userEntityMap,String attrAmount,String attrWriteOff, String typeAttr, String defaultTypeValue, String defaultType, String belongerAttr) throws XbbException {
        List<String> uuids = new ArrayList<>();
        for ( PaasFormDataEntityExt item : formDataList ) {
            if ( StringUtil.isNotEmpty(item.getUuid()) ) {
                uuids.add(item.getUuid());
            }
        }
        List<PaasFormDataEntityExt> paymentSheetEntityExtList = fundHelp.getChildEsDataListByParentUuids(xbbRefTypeEnum, corpid, uuids, linkId, linkBusinessAttr);
        Map<String, Double> paymentSheetEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, Set<String>> belongsMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for ( PaasFormDataEntityExt paymentSheetEntity : paymentSheetEntityExtList ) {
            String uuid = paymentSheetEntity.getUuid();
            JSONObject detailData = paymentSheetEntity.getData();
            boolean writeOffPrepaymentFlag = SheetTypeEnum.onlyWriteOffAmount(detailData.getString(typeAttr));
            Double writeOffAmount = paymentSheetEntityMap.get(uuid) == null ? 0D : paymentSheetEntityMap.get(uuid);
            Set<String> belongs = belongsMap.get(uuid);
            //因为前端明细内恒展示几个固定字段，而预收款核销的amount是为null的，为了方便展示，
            // 把核销金额置入回款金额amount内（目前编辑时不编辑明细，而且就算编辑，在保存时会把预收款核销类型回款单的amount给remove掉）
            Double amount = detailData.getDoubleValue(attrAmount);
            if ( writeOffPrepaymentFlag ) {
                amount = detailData.getDoubleValue(attrWriteOff);
            }
            writeOffAmount = Arith.add(writeOffAmount, amount);
            paymentSheetEntityMap.put(uuid, writeOffAmount);
            JSONArray belongIdArray = FastJsonHelper.getJsonArrFromFormData(paymentSheetEntity.getData(), belongerAttr);
            for ( Object belong : belongIdArray ) {
                UserEntity userEntity = userEntityMap.get(belong.toString());
                if ( Objects.nonNull(userEntity) ) {
                    if ( Objects.isNull(belongs) ) {
                        belongs = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        belongs.add(userEntity.getUserId());
                        belongsMap.put(uuid, belongs);
                    } else {
                        belongs.add(userEntity.getUserId());
                    }
                }
            }
        }
        for ( PaasFormDataEntityExt item : formDataList ) {
            if ( Objects.equals(item.getAlone(), SheetAloneEnum.PARENT.getCode()) ) {
                Double amount = paymentSheetEntityMap.get(item.getUuid());
                JSONObject data = item.getData();
                boolean writeOffPrepaymentFlag = Objects.equals(FastJsonHelper.getStringOrDefaultFromFormData(data, typeAttr, defaultType), defaultTypeValue);
                if ( writeOffPrepaymentFlag ) {
                    item.getData().put(attrWriteOff, amount);
                } else {
                    item.getData().put(attrAmount, amount);
                }
                item.getData().put(belongerAttr, belongsMap.get(item.getUuid()));
                item.setAlone(SheetAloneEnum.CHILD.getCode());
            }
        }
        return formDataList;
    }

    /**
     * 待系列列表筛选解释处理
     * @param explain
     * @param corpid
     * @param explainScreenListDTO
     * @throws XbbException
     */
    private void waitSeriesExplainProcess(List<FieldAttrEntity> explain, String corpid, ExplainScreenListDTO explainScreenListDTO) throws Exception{
        if (Objects.equals(explainScreenListDTO.getBusinessType(),XbbRefTypeEnum.PRODUCT.getCode())){
            explain.clear();
            PaasFormExplainEntity paasFormExplainEnt = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.INVENTORY.getCode(), corpid);
            List<FieldAttrEntity> productExplain = JSON.parseArray(paasFormExplainEnt.getExplains(), FieldAttrEntity.class);
            for (FieldAttrEntity fieldAttrEntity : productExplain) {
                if (Objects.equals(fieldAttrEntity.getAttr(), InventoryEnum.PRODUCT.getAttr())) {
                    fieldAttrEntity.setAttrName("产品");
                    fieldAttrEntity.setAttrNameEn("product");
                    if (Objects.equals(XbbRefTypeEnum.WAIT_OUTSTOCK.getCode(), explainScreenListDTO.getSubBusinessType())) {
                        fieldAttrEntity.setAttr(ContractEnum.PRODUCT.getAttr());
                    }
                    explain.add(fieldAttrEntity);
                    break;
                }
            }
            FieldAttrEntity fieldAttrEntity = explain.get(0);
            FieldAttrEntity fieldAttrPurchase = new FieldAttrEntity();
            BeanUtil.copyProperties(fieldAttrEntity, fieldAttrPurchase);
            if (Objects.equals(explainScreenListDTO.getSubBusinessType(), XbbRefTypeEnum.WAIT_INSTOCK_PURCHASE.getCode())){
                fieldAttrPurchase.setAttrNameEn("purchase");
            }else {
                fieldAttrPurchase.setAttrNameEn("contract");
            }
            fieldAttrPurchase.setAttr("array_2");
            PaasFormExplainEntity paasFormExplainEntx = new PaasFormExplainEntity();
            if (Objects.equals(explainScreenListDTO.getSubBusinessType(),XbbRefTypeEnum.WAIT_INSTOCK_PURCHASE.getCode())){
                paasFormExplainEntx = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.PURCHASE.getCode(), corpid);
                List<FieldAttrEntity> PurchaseExplain = JSON.parseArray(paasFormExplainEntx.getExplains(), FieldAttrEntity.class);
                PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(explainScreenListDTO.getFormId(), corpid);
                List<String> fieldList = WaitInstockEnum.getByBusinessType(XbbRefTypeEnum.PURCHASE.getCode());
                PurchaseExplain = explainHelp.handleExplain(PurchaseExplain, fieldList, paasFormEntityExt);
                //处理linkinfo参数
                saasListHelp.waitInstockPurchaseInfo(PurchaseExplain,explainScreenListDTO);
                SubFormPoJo subForm = new SubFormPoJo();
                subForm.setItems(PurchaseExplain);
                fieldAttrPurchase.setFieldType(FieldTypeEnum.SELECT_PURCHASE.getType());
                fieldAttrPurchase.setFieldId("123ew5rg-5e65-4ef7-fdg4-4fh5441ds4fe");
                fieldAttrPurchase.setSubForm(subForm);
                fieldAttrPurchase.setAttrName("采购合同");
                fieldAttrPurchase.setSaasAttr("waitInstockPurchase");
                explain.add(fieldAttrPurchase);
            } else if (Objects.equals(XbbRefTypeEnum.WAIT_OUTSTOCK.getCode(), explainScreenListDTO.getSubBusinessType()) || Objects.equals(XbbRefTypeEnum.WAIT_PURCHASE.getCode(), explainScreenListDTO.getSubBusinessType())) {
                if (Objects.equals(explainScreenListDTO.getDistributorMark(), DistributorMarkEnum.DISTRIBUTOR.getCode())) {
                    paasFormExplainEntx = paasFormExplainModel.getByBusinessType4Distributor(XbbRefTypeEnum.CONTRACT.getCode(), corpid,DistributorMarkEnum.DISTRIBUTOR.getCode());
                } else {
                    paasFormExplainEntx = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.CONTRACT.getCode(), corpid);
                }
                List<FieldAttrEntity> PurchaseExplain = JSON.parseArray(paasFormExplainEntx.getExplains(), FieldAttrEntity.class);
                PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(explainScreenListDTO.getFormId(), corpid);
                List<String> fieldList = WaitInstockEnum.getByBusinessType(XbbRefTypeEnum.PURCHASE.getCode());
                PurchaseExplain = explainHelp.handleExplain(PurchaseExplain, fieldList, paasFormEntityExt);
                //处理linkinfo参数
                saasListHelp.waitOutContractInfo(PurchaseExplain,explainScreenListDTO);
                SubFormPoJo subForm = new SubFormPoJo();
                subForm.setItems(PurchaseExplain);
                fieldAttrPurchase.setAttrName("合同订单");
                fieldAttrPurchase.setFieldId("123ew5rg-5e65-4ef7-fdg4-4fh5441ds4fe");
                fieldAttrPurchase.setSaasAttr("relyContract");
                fieldAttrPurchase.setSubForm(subForm);
                fieldAttrPurchase.setFieldType(FieldTypeEnum.SELECT_CONTRACT.getType());
                explain.add(fieldAttrPurchase);
            }
            // 塞入展示全部产品筛选按钮
            if (Objects.equals(XbbRefTypeEnum.SMART_REPLENISHMENT.getCode(),explainScreenListDTO.getSubBusinessType())){
                FieldAttrEntity fieldAttrEnt = new FieldAttrEntity();
                fieldAttrEnt.setAttrName("展示全部产品");
                fieldAttrEnt.setAttrNameEn("show all product");
                fieldAttrEnt.setAttr(ProductEnum.IS_NOTIFY.getAttr());
                fieldAttrEnt.setFieldType(FieldTypeEnum.SWITCH.getType());
                explain.add(fieldAttrEnt);
            }
        }else {
            if (Objects.equals(explainScreenListDTO.getSubBusinessType(),XbbRefTypeEnum.WAIT_INSTOCK_PURCHASE.getCode())){
                FieldAttrEntity fieldAttrEntity = new FieldAttrEntity();
                List<FieldAttrEntity> explainEnt = new ArrayList<>();
                fieldAttrEntity.setAttrName("采购合同");
                fieldAttrEntity.setAttrNameEn("contract");
                fieldAttrEntity.setAttr("array_2");
                fieldAttrEntity.setAttrType("array");
                fieldAttrEntity.setFieldType(FieldTypeEnum.SELECT_PURCHASE.getType());
                fieldAttrEntity.setFieldId("123ew5rg-5e65-4ef7-fdg4-4fh5441ds4fe");
                fieldAttrEntity.setSaasAttr("waitInstockPurchase");
                SubFormPoJo subForm = new SubFormPoJo();
                BeanUtil.copyPropertiesList(explain, explainEnt, FieldAttrEntity.class);
                //处理linkinfo参数
                saasListHelp.waitInstockPurchaseInfo(explainEnt,explainScreenListDTO);
                subForm.setItems(explainEnt);
                fieldAttrEntity.setSubForm(subForm);
                explain.clear();
                explain.add(fieldAttrEntity);
            }else if (Objects.equals(explainScreenListDTO.getSubBusinessType(),XbbRefTypeEnum.WAIT_OUTSTOCK.getCode())||Objects.equals(explainScreenListDTO.getSubBusinessType(),XbbRefTypeEnum.WAIT_PURCHASE.getCode())){
                FieldAttrEntity fieldAttrEntity = new FieldAttrEntity();
                List<FieldAttrEntity> explainEnt = new ArrayList<>();
                fieldAttrEntity.setAttrName("合同订单");
                fieldAttrEntity.setAttrNameEn("contract");
                fieldAttrEntity.setAttr("array_2");
                fieldAttrEntity.setFieldId("123ew5rg-5e65-4ef7-fdg4-4fh5441ds4fe");
                fieldAttrEntity.setAttrType("array");
                fieldAttrEntity.setFieldType(FieldTypeEnum.SELECT_CONTRACT.getType());
                fieldAttrEntity.setSaasAttr("relyContract");
                SubFormPoJo subForm = new SubFormPoJo();
                BeanUtil.copyPropertiesList(explain, explainEnt, FieldAttrEntity.class);
                //处理linkinfo参数
                saasListHelp.waitOutContractInfo(explainEnt,explainScreenListDTO);
                subForm.setItems(explainEnt);
                fieldAttrEntity.setSubForm(subForm);
                explain.clear();
                explain.add(fieldAttrEntity);
            }
        }
    }
}
